diff --git a/CLOBBER b/CLOBBER index 361877374292a..cc89fe9f7cdc7 100644 --- a/CLOBBER +++ b/CLOBBER @@ -23,4 +23,4 @@ # don't change CLOBBER for WebIDL changes any more. -Merge day clobber 2023-07-31 \ No newline at end of file +Modified build files in third_party/libwebrtc - Bug 1843113 - Vendor libwebrtc from 8b5bf6dd05 diff --git a/dom/media/systemservices/video_engine/desktop_capture_impl.cc b/dom/media/systemservices/video_engine/desktop_capture_impl.cc index 2274a21e8a287..3f03789fa3948 100644 --- a/dom/media/systemservices/video_engine/desktop_capture_impl.cc +++ b/dom/media/systemservices/video_engine/desktop_capture_impl.cc @@ -358,9 +358,6 @@ static DesktopCaptureOptions CreateDesktopCaptureOptions() { #if defined(WEBRTC_WIN) if (mozilla::StaticPrefs::media_webrtc_capture_allow_directx()) { options.set_allow_directx_capturer(true); - options.set_allow_use_magnification_api(false); - } else { - options.set_allow_use_magnification_api(true); } options.set_allow_cropping_window_capturer(true); # if defined(RTC_ENABLE_WIN_WGC) diff --git a/dom/media/webrtc/jsapi/RTCEncodedVideoFrame.cpp b/dom/media/webrtc/jsapi/RTCEncodedVideoFrame.cpp index f3f8eb4a15423..40afe0e22cdd8 100644 --- a/dom/media/webrtc/jsapi/RTCEncodedVideoFrame.cpp +++ b/dom/media/webrtc/jsapi/RTCEncodedVideoFrame.cpp @@ -49,28 +49,28 @@ RTCEncodedVideoFrame::RTCEncodedVideoFrame( mType = videoFrame.IsKeyFrame() ? RTCEncodedVideoFrameType::Key : RTCEncodedVideoFrameType::Delta; - if (videoFrame.GetMetadata().GetFrameId().has_value()) { - mMetadata.mFrameId.Construct(*videoFrame.GetMetadata().GetFrameId()); + if (videoFrame.Metadata().GetFrameId().has_value()) { + mMetadata.mFrameId.Construct(*videoFrame.Metadata().GetFrameId()); } mMetadata.mDependencies.Construct(); - for (const auto dep : videoFrame.GetMetadata().GetFrameDependencies()) { + for (const auto dep : videoFrame.Metadata().GetFrameDependencies()) { Unused << mMetadata.mDependencies.Value().AppendElement( static_cast(dep), fallible); } - mMetadata.mWidth.Construct(videoFrame.GetMetadata().GetWidth()); - mMetadata.mHeight.Construct(videoFrame.GetMetadata().GetHeight()); - if (videoFrame.GetMetadata().GetSpatialIndex() >= 0) { + mMetadata.mWidth.Construct(videoFrame.Metadata().GetWidth()); + mMetadata.mHeight.Construct(videoFrame.Metadata().GetHeight()); + if (videoFrame.Metadata().GetSpatialIndex() >= 0) { mMetadata.mSpatialIndex.Construct( - videoFrame.GetMetadata().GetSpatialIndex()); + videoFrame.Metadata().GetSpatialIndex()); } - if (videoFrame.GetMetadata().GetTemporalIndex() >= 0) { + if (videoFrame.Metadata().GetTemporalIndex() >= 0) { mMetadata.mTemporalIndex.Construct( - videoFrame.GetMetadata().GetTemporalIndex()); + videoFrame.Metadata().GetTemporalIndex()); } mMetadata.mSynchronizationSource.Construct(videoFrame.GetSsrc()); mMetadata.mPayloadType.Construct(videoFrame.GetPayloadType()); mMetadata.mContributingSources.Construct(); - for (const auto csrc : videoFrame.GetMetadata().GetCsrcs()) { + for (const auto csrc : videoFrame.Metadata().GetCsrcs()) { Unused << mMetadata.mContributingSources.Value().AppendElement(csrc, fallible); } diff --git a/dom/media/webrtc/jsapi/RTCRtpReceiver.cpp b/dom/media/webrtc/jsapi/RTCRtpReceiver.cpp index 7f4d6340d1988..f5dc3ed39a1c1 100644 --- a/dom/media/webrtc/jsapi/RTCRtpReceiver.cpp +++ b/dom/media/webrtc/jsapi/RTCRtpReceiver.cpp @@ -378,9 +378,9 @@ nsTArray> RTCRtpReceiver::GetStatsInternal( constructCommonInboundRtpStats(local); local.mJitter.Construct(audioStats->jitter_ms / 1000.0); local.mPacketsLost.Construct(audioStats->packets_lost); - local.mPacketsReceived.Construct(audioStats->packets_rcvd); + local.mPacketsReceived.Construct(audioStats->packets_received); local.mPacketsDiscarded.Construct(audioStats->packets_discarded); - local.mBytesReceived.Construct(audioStats->payload_bytes_rcvd); + local.mBytesReceived.Construct(audioStats->payload_bytes_received); // Always missing from libwebrtc stats // if (audioStats->estimated_playout_ntp_timestamp_ms) { // local.mEstimatedPlayoutTimestamp.Construct( @@ -409,7 +409,7 @@ nsTArray> RTCRtpReceiver::GetStatsInternal( .ToDom()); } local.mHeaderBytesReceived.Construct( - audioStats->header_and_padding_bytes_rcvd); + audioStats->header_and_padding_bytes_received); local.mFecPacketsReceived.Construct( audioStats->fec_packets_received); local.mFecPacketsDiscarded.Construct( diff --git a/dom/media/webrtc/jsapi/RTCRtpScriptTransformer.cpp b/dom/media/webrtc/jsapi/RTCRtpScriptTransformer.cpp index f02ef74e6bf7d..126020a94fa26 100644 --- a/dom/media/webrtc/jsapi/RTCRtpScriptTransformer.cpp +++ b/dom/media/webrtc/jsapi/RTCRtpScriptTransformer.cpp @@ -316,7 +316,7 @@ void RTCRtpScriptTransformer::TransformFrame( ResolveGenerateKeyFramePromises(videoFrame->GetRid(), videoFrame->GetTimestamp()); if (!videoFrame->GetRid().empty() && - videoFrame->GetMetadata().GetSimulcastIdx() == 0) { + videoFrame->Metadata().GetSimulcastIdx() == 0) { ResolveGenerateKeyFramePromises("", videoFrame->GetTimestamp()); } } diff --git a/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp b/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp index e127f23158484..b31a43b4a6381 100644 --- a/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp +++ b/dom/media/webrtc/libwebrtcglue/AudioConduit.cpp @@ -621,6 +621,32 @@ void WebrtcAudioConduit::OnRtpReceived(webrtc::RtpPacketReceived&& aPacket, aPacket.SequenceNumber(), aPacket.size(), aPacket.Ssrc(), aPacket.Ssrc()); + // Libwebrtc commit cde4b67d9d now expect calls to + // SourceTracker::GetSources() to happen on the call thread. We'll + // grab the value now while on the call thread, and dispatch to main + // to store the cached value if we have new source information. + // See Bug 1845621. + std::vector sources; + if (mRecvStream) { + sources = mRecvStream->GetSources(); + } + + bool needsCacheUpdate = false; + { + AutoReadLock lock(mLock); + needsCacheUpdate = sources != mRtpSources; + } + + // only dispatch to main if we have new data + if (needsCacheUpdate) { + GetMainThreadSerialEventTarget()->Dispatch(NS_NewRunnableFunction( + __func__, [this, rtpSources = std::move(sources), + self = RefPtr(this)]() { + AutoWriteLock lock(mLock); + mRtpSources = rtpSources; + })); + } + mRtpPacketEvent.Notify(); if (mCall->Call()) { mCall->Call()->Receiver()->DeliverRtpPacket( @@ -819,14 +845,7 @@ bool WebrtcAudioConduit::IsSamplingFreqSupported(int freq) const { std::vector WebrtcAudioConduit::GetUpstreamRtpSources() const { MOZ_ASSERT(NS_IsMainThread()); - std::vector sources; - { - AutoReadLock lock(mLock); - if (mRecvStream) { - sources = mRecvStream->GetSources(); - } - } - return sources; + return mRtpSources; } /* Return block-length of 10 ms audio frame in number of samples */ diff --git a/dom/media/webrtc/libwebrtcglue/AudioConduit.h b/dom/media/webrtc/libwebrtcglue/AudioConduit.h index 807f6c8b4057f..86f16ef6d19b6 100644 --- a/dom/media/webrtc/libwebrtcglue/AudioConduit.h +++ b/dom/media/webrtc/libwebrtcglue/AudioConduit.h @@ -289,6 +289,10 @@ class WebrtcAudioConduit : public AudioSessionConduit, // To track changes needed to mRtpSendBaseSeqs. std::map mRtpSendBaseSeqs_n; + // Written only on the main thread. Guarded by mLock, except for + // reads on the main thread. + std::vector mRtpSources; + // Thread safe Atomic mTransportActive = Atomic(false); MediaEventProducer mRtcpByeEvent; diff --git a/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp b/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp index 1f7ebf81262a4..b4faf5107a178 100644 --- a/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp +++ b/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp @@ -1535,6 +1535,32 @@ void WebrtcVideoConduit::OnRtpReceived(webrtc::RtpPacketReceived&& aPacket, aPacket.SequenceNumber(), aPacket.size(), aPacket.Ssrc(), aPacket.Ssrc()); + // Libwebrtc commit cde4b67d9d now expect calls to + // SourceTracker::GetSources() to happen on the call thread. We'll + // grab the value now while on the call thread, and dispatch to main + // to store the cached value if we have new source information. + // See Bug 1845621. + std::vector sources; + if (mRecvStream) { + sources = mRecvStream->GetSources(); + } + + bool needsCacheUpdate = false; + { + MutexAutoLock lock(mMutex); + needsCacheUpdate = sources != mRtpSources; + } + + // only dispatch to main if we have new data + if (needsCacheUpdate) { + GetMainThreadSerialEventTarget()->Dispatch(NS_NewRunnableFunction( + __func__, [this, rtpSources = std::move(sources), + self = RefPtr(this)]() { + MutexAutoLock lock(mMutex); + mRtpSources = rtpSources; + })); + } + mRtpPacketEvent.Notify(); if (mCall->Call()) { mCall->Call()->Receiver()->DeliverRtpPacket( @@ -1928,14 +1954,7 @@ void WebrtcVideoConduit::SetTransportActive(bool aActive) { std::vector WebrtcVideoConduit::GetUpstreamRtpSources() const { MOZ_ASSERT(NS_IsMainThread()); - std::vector sources; - { - MutexAutoLock lock(mMutex); - if (mRecvStream) { - sources = mRecvStream->GetSources(); - } - } - return sources; + return mRtpSources; } void WebrtcVideoConduit::RequestKeyFrame(FrameTransformerProxy* aProxy) { diff --git a/dom/media/webrtc/libwebrtcglue/VideoConduit.h b/dom/media/webrtc/libwebrtcglue/VideoConduit.h index f4e6583a21b19..1d4c86f909d9f 100644 --- a/dom/media/webrtc/libwebrtcglue/VideoConduit.h +++ b/dom/media/webrtc/libwebrtcglue/VideoConduit.h @@ -487,6 +487,10 @@ class WebrtcVideoConduit // Protected by mRendererMonitor dom::RTCVideoFrameHistoryInternal mReceivedFrameHistory; + // Written only on the main thread. Guarded by mMutex, except for + // reads on the main thread. + std::vector mRtpSources; + // Thread safe Atomic mTransportActive = Atomic(false); MediaEventProducer mRtcpByeEvent; diff --git a/dom/media/webrtc/third_party_build/default_config_env b/dom/media/webrtc/third_party_build/default_config_env index fe97cf84c977c..2538e77aa1e0b 100644 --- a/dom/media/webrtc/third_party_build/default_config_env +++ b/dom/media/webrtc/third_party_build/default_config_env @@ -9,34 +9,34 @@ export MOZ_LIBWEBRTC_SRC=$STATE_DIR/moz-libwebrtc # the commit summary as each upstream commit is vendored into the # mercurial repository. The bug used for the v106 fast-forward was # 1800920. -export MOZ_FASTFORWARD_BUG="1839451" +export MOZ_FASTFORWARD_BUG="1843113" # MOZ_NEXT_LIBWEBRTC_MILESTONE and MOZ_NEXT_FIREFOX_REL_TARGET are # not used during fast-forward processing, but facilitate generating this # default config. To generate an default config for the next update, run # bash dom/media/webrtc/third_party_build/update_default_config_env.sh -export MOZ_NEXT_LIBWEBRTC_MILESTONE=113 -export MOZ_NEXT_FIREFOX_REL_TARGET=117 +export MOZ_NEXT_LIBWEBRTC_MILESTONE=114 +export MOZ_NEXT_FIREFOX_REL_TARGET=118 # For Chromium release branches, see: # https://chromiumdash.appspot.com/branches -# Chromium's v112 release branch was 5615. This is used to pre-stack +# Chromium's v113 release branch was 5672. This is used to pre-stack # the previous release branch's commits onto the appropriate base commit # (the first common commit between trunk and the release branch). -export MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM="5615" +export MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM="5672" -# New target release branch for v113 is branch-heads/5672. This is used +# New target release branch for v114 is branch-heads/5735. This is used # to calculate the next upstream commit. -export MOZ_TARGET_UPSTREAM_BRANCH_HEAD="branch-heads/5672" +export MOZ_TARGET_UPSTREAM_BRANCH_HEAD="branch-heads/5735" # For local development 'mozpatches' is fine for a branch name, but when # pushing the patch stack to github, it should be named something like -# 'moz-mods-chr113-for-rel117'. +# 'moz-mods-chr114-for-rel118'. export MOZ_LIBWEBRTC_BRANCH="mozpatches" # After elm has been merged to mozilla-central, the patch stack in # moz-libwebrtc should be pushed to github. The script # push_official_branch.sh uses this branch name when pushing to the # public repo. -export MOZ_LIBWEBRTC_OFFICIAL_BRANCH="moz-mods-chr113-for-rel117" +export MOZ_LIBWEBRTC_OFFICIAL_BRANCH="moz-mods-chr114-for-rel118" diff --git a/third_party/libwebrtc/AUTHORS b/third_party/libwebrtc/AUTHORS index b3cbb4db351de..83a968d326736 100644 --- a/third_party/libwebrtc/AUTHORS +++ b/third_party/libwebrtc/AUTHORS @@ -133,6 +133,7 @@ Yura Yaroshevich Yuriy Pavlyshak Yusuke Suzuki Pengfei Han +Yingying Ma # END individuals section. # BEGIN organizations section. diff --git a/third_party/libwebrtc/BUILD.gn b/third_party/libwebrtc/BUILD.gn index 6eb14773b0a70..00444cdbfaba6 100644 --- a/third_party/libwebrtc/BUILD.gn +++ b/third_party/libwebrtc/BUILD.gn @@ -503,6 +503,16 @@ if (!build_with_chromium) { "api/task_queue", "api/task_queue:default_task_queue_factory", "api/test/metrics", + "api/video_codecs:video_decoder_factory_template", + "api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "api/video_codecs:video_encoder_factory_template", + "api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "api/video_codecs:video_encoder_factory_template_open_h264_adapter", "audio", "call", "common_audio", @@ -527,6 +537,16 @@ if (!build_with_chromium) { "api/task_queue", "api/task_queue:default_task_queue_factory", "api/test/metrics", + "api/video_codecs:video_decoder_factory_template", + "api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "api/video_codecs:video_encoder_factory_template", + "api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "api/video_codecs:video_encoder_factory_template_open_h264_adapter", "logging:rtc_event_log_api", "p2p:rtc_p2p", "pc:libjingle_peerconnection", @@ -542,13 +562,6 @@ if (!build_with_chromium) { ] } - if (rtc_include_builtin_video_codecs) { - deps += [ - "api/video_codecs:builtin_video_decoder_factory", - "api/video_codecs:builtin_video_encoder_factory", - ] - } - if (build_with_mozilla) { deps += [ "api/video:video_frame", diff --git a/third_party/libwebrtc/DEPS b/third_party/libwebrtc/DEPS index 32f66f099554b..68bf5180d9e7d 100644 --- a/third_party/libwebrtc/DEPS +++ b/third_party/libwebrtc/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': '226d9c69f95187b1ca9aa75b03daa0f40fb6c585', + 'chromium_revision': '0c1d6778e0f221681f373cdb2837b0336381abbe', # 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/gn/', - 'fuchsia_version': 'version:12.20230323.1.1', + 'fuchsia_version': 'version:12.20230424.2.1', # By default, download the fuchsia images from the fuchsia GCS bucket. 'fuchsia_images_bucket': 'fuchsia', 'checkout_fuchsia': False, @@ -36,7 +36,7 @@ vars = { 'checkout_fuchsia_product_bundles': '"{checkout_fuchsia_boot_images}" != ""', # reclient CIPD package version - 'reclient_version': 're_client_version:0.99.0.3f95625-gomaip', + 'reclient_version': 're_client_version:0.101.0.6210d0d-gomaip', # ninja CIPD package version # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja @@ -46,30 +46,30 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@a49af702a7bc9939c2df7b2137c4f7f462078145', + 'https://chromium.googlesource.com/chromium/src/base@fe22033c21d399a340b3f4604722463d9da25c6e', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@b83d7798d5a9b453c31f58cb6a673c2b5d3dcdc7', + 'https://chromium.googlesource.com/chromium/src/build@a9d28a095c8b349f8319ee0d241a78e2c849928f', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@0a6c69640f1841d9109eac70a25af310d4c1d8c7', + 'https://chromium.googlesource.com/chromium/src/buildtools@539a6f68735c631f57ae33096e9e7fc059e049cf', # 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@e5fd242e24a263aa36c2fe9f42f709d6fca15f5e', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@a2df0a6e728e1c26fe55ea4bea29b6053f361755', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@e1bf65702259e2760279dfb11c087c8ef07bdb8f', + 'https://chromium.googlesource.com/chromium/src/testing@ee4801b4e9c2d945fff5236d8518511e6c00a29e', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@af346205b359172a876a8db3a91d691064fbd4f2', + 'https://chromium.googlesource.com/chromium/src/third_party@4f8bf4c6885ab577c7577c4cdd11d04eaf78e9ca', 'src/buildtools/linux64': { 'packages': [ { 'package': 'gn/gn/linux-${{arch}}', - 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', + 'version': 'git_revision:5a004f9427a050c6c393c07ddb85cba8ff3849fa', } ], 'dep_type': 'cipd', @@ -79,7 +79,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/mac-${{arch}}', - 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', + 'version': 'git_revision:5a004f9427a050c6c393c07ddb85cba8ff3849fa', } ], 'dep_type': 'cipd', @@ -89,7 +89,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/windows-amd64', - 'version': 'git_revision:41fef642de70ecdcaaa26be96d56a0398f95abd4', + 'version': 'git_revision:5a004f9427a050c6c393c07ddb85cba8ff3849fa', } ], 'dep_type': 'cipd', @@ -111,11 +111,11 @@ deps = { 'src/buildtools/clang_format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@f97059df7f8b205064625cdb5f97b56668a125ef', 'src/buildtools/third_party/libc++/trunk': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@e44019bfac2b2d3ebe1618628884f85c8600e322', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@bff81b702ff4b7f74b1c0ed02a4bcf6c2744a90b', 'src/buildtools/third_party/libc++abi/trunk': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@9643f2cf13d6935a84a30b7da7de53327733e190', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@307bd163607c315d46103ebe1d68aab44bf93986', 'src/buildtools/third_party/libunwind/trunk': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@29a6dda8c6588ba4abeafdb21be531e757983e31', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@2795322d57001de8125cfdf18cef804acff69e35', 'src/third_party/ninja': { 'packages': [ @@ -151,7 +151,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/aapt2', - 'version': '36NqCian2RIwuM6SFfizdUgKoXyZhy3q6pFfsws0szYC', + 'version': 'fFfHyo80O9opPFsbOisSHF4d3tV4GGxLgxXWzGRuY2IC', }, ], 'condition': 'checkout_android', @@ -162,7 +162,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/bundletool', - 'version': 'TpDdbF-PPgwL0iOVsdLM07L-DUp2DV3hgzCMmPd2_GUC', + 'version': 'xnKkaX2u7XVfsUzExic0KW3jYMINpI16Ll9QYESBoI8C', }, ], 'condition': 'checkout_android', @@ -170,11 +170,11 @@ deps = { }, 'src/third_party/boringssl/src': - 'https://boringssl.googlesource.com/boringssl.git@74646566e93de7551bfdfc5f49de7462f13d1d05', + 'https://boringssl.googlesource.com/boringssl.git@6776d5cd8fcdf6c5e05bae2d655076dbeaa56103', 'src/third_party/breakpad/breakpad': - 'https://chromium.googlesource.com/breakpad/breakpad.git@abb105db21e962eda5b7d9b7a0ac8dd701e0b987', + 'https://chromium.googlesource.com/breakpad/breakpad.git@9bf8d1ec526cec139b2d3fba148ce81ccf2cceab', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@6834ebcc0933724042c4b8535bf85f04ff41dfd6', + 'https://chromium.googlesource.com/catapult.git@cae7ec667dee9f5c012b54ee9ffee94eb7beda14', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -183,9 +183,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@479e1e9055020c8d1351bf2194d0a606aeca93d5', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@6e714e6dfe62110c95fafed4bdeb365a69c6a77e', 'src/third_party/ffmpeg': - 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@a51c75b09b3f54ab2d3efe583dcc89ba84d24c0d', + 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@8d21d41d8bec5c0b266ee305d1a708dc5c23b594', 'src/third_party/flatbuffers/src': 'https://chromium.googlesource.com/external/github.com/google/flatbuffers.git@a56f9ec50e908362e20254fcef28e62a2f148d91', 'src/third_party/grpc/src': { @@ -197,11 +197,11 @@ deps = { 'condition': 'checkout_linux', }, 'src/third_party/freetype/src': - 'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@4d8db130ea4342317581bab65fc96365ce806b77', + 'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@9806414c15230d253d5219ea0dafeddb717307b1', 'src/third_party/harfbuzz-ng/src': 'https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git@2822b589bc837fae6f66233e2cf2eef0f6ce8470', 'src/third_party/google_benchmark/src': { - 'url': 'https://chromium.googlesource.com/external/github.com/google/benchmark.git@efc89f0b524780b1994d5dddd83a92718e5be492', + 'url': 'https://chromium.googlesource.com/external/github.com/google/benchmark.git@b177433f3ee2513b1075140c723d73ab8901790f', }, # WebRTC-only dependency (not present in Chromium). 'src/third_party/gtest-parallel': @@ -219,13 +219,13 @@ deps = { 'src/third_party/googletest/src': 'https://chromium.googlesource.com/external/github.com/google/googletest.git@af29db7ec28d6df1c7f0f745186884091e602e07', 'src/third_party/icu': { - 'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@1e49ac26ddc712b1ab702f69023cbc57e9ae6628', + 'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@d8daa943f64cd5dd2a55e9baf2e655ab4bfa5ae9', }, 'src/third_party/jdk': { 'packages': [ { 'package': 'chromium/third_party/jdk', - 'version': '-FR8HTNcMfxy7J2HUaWVa0QmEE4f68iotzvFbqOj2LEC', + 'version': '2Of9Pe_OdO4xoAATuiLDiMVNebKTNO3WrwJGqil4RosC', }, ], 'condition': 'host_os == "linux" and checkout_android', @@ -254,7 +254,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/kotlin_stdlib', - 'version': 'XON2v801ZWS7FjApXO8Ev7Me7cOsIAnmqzyCXJuMwJ0C', + 'version': 'gizyEP29NQpAimwviO2pgSrqvx0YgAvSUNc5V6hvfroC', }, ], 'condition': 'checkout_android', @@ -265,7 +265,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/kotlinc', - 'version': 'bCZedwoM-hb1pP1QKzA3P5aR4zjZltqLj4JQpmQsHuUC', + 'version': 'Ly0WLNcc5HwMFsqSGLX4OrQ8nivZ9w8nSJyU7BsPIRkC', }, ], 'condition': 'checkout_android', @@ -281,17 +281,17 @@ deps = { 'src/third_party/dav1d/libdav1d': 'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@d426d1c91075b9c552b12dd052af1cd0368f05a2', 'src/third_party/libaom/source/libaom': - 'https://aomedia.googlesource.com/aom.git@16e24831397a22504541e8ec2674e3cf219e0ac5', + 'https://aomedia.googlesource.com/aom.git@5a0903824082f41123e8365b5b99ddb6ced8971c', 'src/third_party/libunwindstack': { 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@4dbfa0e8c844c8e243b297bc185e54a99ff94f9e', 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@be5933f4b25db0b6db546ed2949c52af2e0356fd', + 'https://android.googlesource.com/platform/external/perfetto.git@20b114cd063623e63ef1b0a31167d60081567e51', 'src/third_party/libvpx/source/libvpx': - 'https://chromium.googlesource.com/webm/libvpx.git@394de691a0ef570fc49943f565ad53ee0d22a7f3', + 'https://chromium.googlesource.com/webm/libvpx.git@27171320f5e36f7b18071bfa1d9616863ca1b4e8', 'src/third_party/libyuv': - 'https://chromium.googlesource.com/libyuv/libyuv.git@3f219a3501e555ffef7aeaa90abbaf90a90d2258', + 'https://chromium.googlesource.com/libyuv/libyuv.git@77c2121f7e6b8e694d6e908bbbe9be24214097da', 'src/third_party/lss': { 'url': 'https://chromium.googlesource.com/linux-syscall-support.git@ce877209e11aa69dcfffbd53ef90ea1d07136521', 'condition': 'checkout_android or checkout_linux', @@ -307,12 +307,12 @@ deps = { }, 'src/third_party/openh264/src': - 'https://chromium.googlesource.com/external/github.com/cisco/openh264@db956674bbdfbaab5acdd3fdb4117c2fef5527e9', + 'https://chromium.googlesource.com/external/github.com/cisco/openh264@09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/r8': { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'EGf7RQo3stt-vPTw69TaMGuNtnOx0Dbk1O-MBquwswYC', + 'version': 'EasU4gRQz5fwXjPOM82KyQOTpv6FGp_Q7wUg1l94iHYC', }, ], 'condition': 'checkout_android', @@ -336,7 +336,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@da1dc8ec60011baf22a4e87430b11afb792f5f42', + 'https://chromium.googlesource.com/chromium/src/tools@bafae7909cbbcd277d29c0da0809001a8d6f4a14', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -349,17 +349,6 @@ deps = { 'dep_type': 'cipd', }, - 'src/third_party/android_support_test_runner': { - 'packages': [ - { - 'package': 'chromium/third_party/android_support_test_runner', - 'version': '96d4bf848cd210fdcbca6bcc8c1b4b39cbd93141', - }, - ], - 'condition': 'checkout_android', - 'dep_type': 'cipd', - }, - 'src/third_party/byte_buddy': { 'packages': [ { @@ -413,7 +402,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'Bd5GuYdu-KY7DAsP-QU0XofyaFYU7ySZX8QQpca7j3sC', + 'version': 'vf4nNaoNXCQUtS2Ye70vMzrPTUUdLtAn9U9U3hYqkAQC', }, ], 'condition': 'checkout_android', @@ -424,7 +413,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': '_aoHU11YhUwqKZXVXsn5otnhI-ZVGFT7h1Z9eCcAZM0C', + 'version': '1g5VzjyIYFR1uY6iwEOLv8aZp-OQJQc5W2U-dPyg97IC', }, ], 'condition': 'checkout_android', @@ -463,7 +452,7 @@ deps = { }, { 'package': 'chromium/third_party/android_sdk/public/cmdline-tools', - 'version': '3Yn5Sn7BMObm8gsoZCF0loJMKg9_PpgU07G9DObCLdQC', + 'version': 'EWnL2r7oV5GtE9Ef7GyohyFam42wtMtEKYU4dCb3U1YC', }, ], 'condition': 'checkout_android', @@ -518,7 +507,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/turbine', - 'version': 'epnqx7Yf9QxgyDaU87KJ1fLQvdZ_Mho_JjfpjmIBYWYC', + 'version': 'j0GanRK31QhKNs04PYT0D3ls32n6IrjrAL8bR4dv9jMC', }, ], 'condition': 'checkout_android', @@ -529,11 +518,11 @@ deps = { 'packages': [ { 'package': 'infra/tools/luci/isolate/${{platform}}', - 'version': 'git_revision:320bf3ed60cd4d24549d0ea9ee3a94394f2665ce', + 'version': 'git_revision:e91834850a06011c64eb9a24f317371194bde3de', }, { 'package': 'infra/tools/luci/swarming/${{platform}}', - 'version': 'git_revision:320bf3ed60cd4d24549d0ea9ee3a94394f2665ce', + 'version': 'git_revision:e91834850a06011c64eb9a24f317371194bde3de', }, ], 'dep_type': 'cipd', @@ -1162,17 +1151,6 @@ deps = { 'dep_type': 'cipd', }, - 'src/third_party/android_deps/libs/com_google_android_gms_play_services_fido': { - 'packages': [ - { - 'package': 'chromium/third_party/android_deps/libs/com_google_android_gms_play_services_fido', - 'version': 'version:2@19.0.0-beta.cr1', - }, - ], - 'condition': 'checkout_android', - 'dep_type': 'cipd', - }, - 'src/third_party/android_deps/libs/com_google_android_gms_play_services_flags': { 'packages': [ { @@ -1771,7 +1749,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_deps/libs/com_squareup_wire_wire_runtime_jvm', - 'version': 'version:2@4.4.3.cr1', + 'version': 'version:2@4.5.1.cr1', }, ], 'condition': 'checkout_android', @@ -2057,7 +2035,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7', - 'version': 'version:2@1.8.0.cr1', + 'version': 'version:2@1.8.20.cr1', }, ], 'condition': 'checkout_android', @@ -2068,7 +2046,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8', - 'version': 'version:2@1.8.0.cr1', + 'version': 'version:2@1.8.20.cr1', }, ], 'condition': 'checkout_android', @@ -2079,7 +2057,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android', - 'version': 'version:2@1.6.1.cr1', + 'version': 'version:2@1.6.4.cr1', }, ], 'condition': 'checkout_android', @@ -2090,7 +2068,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm', - 'version': 'version:2@1.6.1.cr1', + 'version': 'version:2@1.6.4.cr1', }, ], 'condition': 'checkout_android', diff --git a/third_party/libwebrtc/README.moz-ff-commit b/third_party/libwebrtc/README.moz-ff-commit index 83c6a7bfe77f4..b42cea31e8c99 100644 --- a/third_party/libwebrtc/README.moz-ff-commit +++ b/third_party/libwebrtc/README.moz-ff-commit @@ -22626,3 +22626,882 @@ d3e765e4eb # MOZ_LIBWEBRTC_SRC=/Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh # base of lastest vendoring f6ab0b438e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6bd1d88910 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ec8b84b740 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c848268ab1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9f3ccf291e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +aaf14f6d45 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +94b51210f8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2d1fa4713f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7f60e5f753 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +55c7298c2b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0e5501f0ff +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a077c810a8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c5079e299b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +da1445d442 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +cbe5d81498 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +335d084b3b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +86ad48cb37 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6fd5f33d45 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +65c675263f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1063e30df8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b8555e791a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9a98d0b8e0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7bb9322e9e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +cac9a55ddf +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e2a2278b2f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6be448fa45 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8e781a1bb1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +55f72800b4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a3f7b54518 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e14abcb20b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +90d5e7d655 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9204210718 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ef5cd7d336 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a5adf13091 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +cea6a0d10a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +56548988e9 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c99753ac8f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +48476d84d5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f21cdb0afa +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d32e5b3078 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e08f9a94fa +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d7510fe1e4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d6c4b1641d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +089758dbc5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +58b049373e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d93b7b91e0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1821faaa6c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f01e97063a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ae049f1924 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f6ce1d39ee +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2b742f7eaa +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e7482b403d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +49572e3438 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f767fc0fb1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d094ad7e2e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +46849fc73c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d116350b48 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c33d8e2c14 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4f7ade5c58 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +91160efca4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +77158ace75 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +910b225d82 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c888db24a4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1158bde7c2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +80558f49fa +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +49e5587e64 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e1e94ad4c8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2bac7ef244 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +3beacb7a87 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +adfc1601c1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +30f3d2710d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0fe65102cc +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +dc806fd16a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1f708ef2ff +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2b00c4e1af +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8be11b0d05 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +bd46bb7660 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +bc959b15e2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f34aa1e40b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +5bb3274f40 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a0e4ce0e81 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d549e4b6ce +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +44437d35cd +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0587aaea1a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e0727118f1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f3bdce9a99 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +098cfbdc82 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +13fffbbe40 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7d9cf9a537 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2cafacfe86 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +755ffa7e8a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +89f095cb07 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0b148e91a4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +40a0e3191a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4b61f3a0c6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +527196508c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +31af34ba8c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0a3ad1a561 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8481f6358e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +fe53fec24e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1b3c89878e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d09103718e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a3ff334cf1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7f16fcda0f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +65f5160195 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7ceb49c7b8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +40cb0091a1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +727014a5f1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0b06b2785b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +deb25d2f45 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0e1d3c5675 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b8219a1f98 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +27d70f3133 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +419e48fbc5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f7ed83f68e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a13b4d1d30 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d2535a53cf +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b51c0ce271 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d0dfe95bf0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ba5f633a94 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +209a448307 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f5655d00ea +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7454fdd12b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a870bf8183 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +fba851559b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f9e13f8813 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +56577ccc8f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1b243e026b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +5499690916 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +5d1ec8262e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9bbd9598b8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8fbd0e108e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +23a864bf54 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ee17823c7f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1c3c55e1a7 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6d8937cfff +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8329cf030c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9658f47459 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +da9e284308 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d4fe3ce902 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e807ef2245 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b515c17dba +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6cabf35a42 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +26f22e0496 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +aab1bdea11 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c2d37895a2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +89facfc421 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +fb65d23d73 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e25c1229c5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d5ebc33562 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0bfecdc84a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +eb99300bb5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +401c14aaf6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +77c47947ad +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b70a36e770 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +dd557fdb1e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a50a81a150 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +28d92f6804 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +779aadeb2e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +73f048daf0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e686b1fc8b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +35f2b89ee4 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b4a45546b7 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +22f14fe83b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7ba354a426 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2a3942fec1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1db3209e70 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +50b0a76ee7 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +08dcd7a526 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0f87b38535 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d12582ae03 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +add7ac0ded +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +79ea89ee74 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e02d50931b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +921448fbc6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0ae4d249c7 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +469e73c897 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b00d63c88b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +5248228d79 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +26d1b26277 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ec2670e631 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +82f63501cf +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7720331b40 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +514829cac8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c381c33767 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +61684fc814 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +df0862c7ec +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1b77daea81 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +fb8e3de0a8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d77f2212b0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +51cd709d11 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c087d0cce5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +06e2148889 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +71693887e0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +239db68b17 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b9313b9584 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +242ca2b5d1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +fa6da49db3 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2ec6a6c578 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6b4702355b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +58e8cb0553 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0a4a9846fc +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6f7c7568af +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +298313534d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0774b8f4fe +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d21d87730a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +14375c25e8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4ec56a3aa0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4beafa38d5 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b812b7a86b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4665d60e09 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +37879e9867 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ea1502accb +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6cf12bbe32 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4730201454 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +59d09aeeee +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e42bf81486 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +45eae34693 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1f251dd67e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8b5bf6dd05 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +69c8d3c843 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +56e830819f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +bbde8b60a3 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +aa3c9f2972 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +5c5b7b38ba +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +61e8b59701 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +95e7a0398c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +580b0f944b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +70f30d3066 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b43f065728 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +eccc0bb9f9 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e9b25ab5be +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2c0689ffad +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f9ffd68d8e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +88429d572b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +1fdb40c00f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +adbd9e939b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8a10dca8ff +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ef86a0fee9 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2080dacfb7 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c018bae807 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c2c057480e +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +67f2109544 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +527701a8f2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9e734a660b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +eba7cee1da +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d3416972dd +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e2e70e5474 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4ae238770b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +3c6b46fc16 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +049b0dc7dd +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7c0525b98b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6f86f6af00 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +802e8e5fdb +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +7aa6a72dc6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ff6cd53303 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +691b447c53 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +51c632c13b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +325b3caac6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a736f30a5f +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +0421294df0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e91c76875a +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +014cbed9d2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b810a64db1 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +4e0bdf550b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +683f3165f9 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +daaa6ab5a8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +94e5817759 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d1e5dedffe +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +c22893b3f6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +70fc5a2e41 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +94774d475b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +47701c8c9b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +01716663a9 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +39e859901b +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +eeae962997 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6a7bf10d60 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6c2f7602ca +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +f9e3bdd2ce +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ba41b40461 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +6a34c75d5d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +031ebc42e6 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +cde4b67d9d +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +83c8a3b885 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b11caa366c +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +8a9f3a8f53 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +b035dcc0a2 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +52275845a0 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +df7df199ab +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +9d99682446 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +ecab2a49da +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +e46e37b6f8 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +d20849d071 +# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +a624ee1be7 diff --git a/third_party/libwebrtc/README.mozilla b/third_party/libwebrtc/README.mozilla index 78cd0f6ed3be5..43f3d2e3c5cfe 100644 --- a/third_party/libwebrtc/README.mozilla +++ b/third_party/libwebrtc/README.mozilla @@ -15106,3 +15106,589 @@ libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc c libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-06-30T19:53:42.763579. # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc libwebrtc updated from /Users/jan-ivar/moz/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-06-30T19:55:01.390853. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T20:49:53.475507. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:06:24.490193. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:10:34.872809. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:11:45.651984. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:12:42.555794. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:13:40.622086. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:14:37.864326. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:15:34.887438. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:16:41.842788. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:17:38.956569. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:18:35.809451. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:20:08.794446. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:21:04.638779. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:21:59.954139. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:22:56.794811. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:23:52.878073. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:25:24.684796. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:26:23.830218. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:27:19.851384. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:28:16.701616. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:29:12.971097. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:30:08.915277. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:31:53.236625. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:32:54.993511. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:33:54.449199. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:34:52.683902. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:35:50.001389. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:37:20.607783. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:38:17.867951. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:39:36.686475. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:40:34.024601. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:41:31.870875. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:42:28.539188. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:43:25.466631. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:44:23.510815. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:45:22.323241. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:46:24.484302. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:47:21.931929. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:48:18.671228. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:49:14.754739. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:50:11.811465. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:51:45.814976. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:52:44.666791. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:53:42.676533. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:54:40.931769. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:55:41.627335. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:57:15.709306. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:58:15.038558. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T21:59:13.622631. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:01:11.806903. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:02:10.658443. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:03:31.846722. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:04:31.029875. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:05:26.733995. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:06:24.803257. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:07:22.520441. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:08:22.611515. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:09:20.353586. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:10:18.725295. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:11:16.278942. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:12:14.366056. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:13:12.042892. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:14:09.897935. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:15:07.622166. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:16:05.580465. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:16:59.853275. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:18:31.729087. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:20:03.643576. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:21:38.522140. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:22:38.710699. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:24:10.547052. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:25:08.449421. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:26:40.308499. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:38:23.132008. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:39:58.760342. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:41:30.442259. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:42:24.832713. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:43:56.055433. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:44:53.780140. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:46:24.588135. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:47:59.796000. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:48:58.086395. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:50:33.898521. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:52:05.809295. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:53:03.917392. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:54:02.783352. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:55:03.620007. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:56:38.899758. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:58:11.658212. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T22:59:44.659095. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:00:43.584922. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:01:40.791957. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:03:13.169025. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:04:11.690768. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:05:08.892796. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:06:08.174098. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:07:05.779606. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:08:03.906512. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:09:27.710489. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:10:27.515123. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:11:25.887096. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:12:23.692173. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:13:56.350396. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:14:53.003970. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:15:48.482657. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:16:45.926281. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:17:42.772827. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:18:37.710325. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:19:35.707094. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:20:35.743123. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:22:08.694330. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:23:06.028293. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:24:41.402109. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:25:36.925893. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:26:35.567050. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:27:33.586095. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:28:32.601247. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:29:31.838731. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:30:31.569817. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:31:29.698974. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:32:33.887195. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:33:34.236084. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:34:33.770847. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:35:32.739161. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:36:27.913933. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:38:01.929230. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:38:59.762736. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:39:57.852959. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:40:56.845539. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:41:54.632568. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:42:54.680632. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:43:53.728149. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:44:51.892348. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:45:51.388362. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:46:50.801871. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:47:49.739884. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:48:47.749145. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:50:22.440412. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:51:55.812692. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:52:54.585279. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:53:52.971265. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:54:51.746227. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:55:49.590552. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:56:48.662543. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:57:58.803888. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:58:58.835871. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-13T23:59:57.409823. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:00:56.470695. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:01:55.385205. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:03:34.900993. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:04:33.686100. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:05:32.267490. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:06:43.889024. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:07:49.979922. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:08:49.862206. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:10:28.749068. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:12:01.908030. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:13:03.051902. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:14:07.849341. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:15:42.386824. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:17:19.076799. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:18:21.678463. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:19:57.586727. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:21:33.716021. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:22:32.645998. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:24:06.608342. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:25:05.740252. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:26:42.780847. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:28:22.610855. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:29:24.859148. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:31:01.525108. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:31:59.798456. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:33:38.079076. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:34:40.803721. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:35:41.955684. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:36:41.738679. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:37:41.586401. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:38:41.729189. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:39:41.739478. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:41:19.542777. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:42:44.519236. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:44:20.954578. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:45:21.583526. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:46:21.859851. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:47:44.760528. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:49:23.894212. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:50:23.498195. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:51:34.282131. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:53:10.896920. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:54:47.656406. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T00:55:48.631321. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:46:26.286621. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:48:46.473161. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:49:44.713244. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:51:22.319663. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:52:31.811941. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:53:29.932245. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:54:29.926874. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:55:28.393498. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:56:27.701094. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:57:28.769820. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:58:55.578242. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T14:59:53.835207. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:00:53.655896. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:01:52.632555. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:02:51.716263. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:03:53.805771. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:04:53.629700. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:05:55.698127. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:06:58.786145. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:07:58.988047. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:09:58.627613. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:11:32.743241. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:12:31.760453. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:14:06.555520. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:15:41.734955. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:17:20.615927. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T15:18:19.997539. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:04:24.780100. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:23:21.627864. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:25:00.237203. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:26:00.876429. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:27:35.020053. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:28:35.725790. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:29:35.335768. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:30:36.901422. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:31:57.969857. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:33:34.800132. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:34:32.871421. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:35:30.709303. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:36:28.905384. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:37:28.736123. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:38:27.570957. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:40:02.498534. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:41:00.633878. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:41:58.667733. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:42:59.025143. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:43:57.199288. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T16:44:55.718453. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:18:24.895333. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:50:51.832253. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:51:54.123718. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:52:52.650054. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:54:28.581902. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:55:50.934534. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:57:29.393627. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:58:31.998784. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T17:59:29.687476. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:00:27.963903. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:01:27.342145. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:02:25.492453. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:03:24.103062. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:13:13.865157. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:35:07.575476. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:36:08.715625. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:37:10.202887. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:38:12.018848. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:39:12.282108. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:40:13.876931. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:41:14.716102. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:42:12.793049. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:43:52.092484. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:44:52.952951. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:45:52.373046. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:46:53.957058. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:47:52.506533. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:48:50.808214. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:49:49.009539. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:51:25.642833. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:52:28.875713. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:53:26.801191. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:54:24.373204. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:55:24.028624. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:56:57.826064. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:57:58.974131. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T18:59:01.633460. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T19:29:02.500022. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T19:30:00.669283. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T19:49:27.059212. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T19:56:57.039333. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T19:57:54.681324. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:28:48.372494. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:52:15.724202. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:53:16.938607. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:54:15.172203. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:55:51.660766. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:56:52.434746. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:58:08.778095. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T20:59:06.341337. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T21:00:06.469027. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T21:01:04.634768. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T21:02:05.862286. +# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-07-14T21:03:04.820705. diff --git a/third_party/libwebrtc/api/BUILD.gn b/third_party/libwebrtc/api/BUILD.gn index 86552cdab5973..3ef383e1bce62 100644 --- a/third_party/libwebrtc/api/BUILD.gn +++ b/third_party/libwebrtc/api/BUILD.gn @@ -498,6 +498,7 @@ rtc_source_set("video_quality_analyzer_api") { deps = [ ":array_view", ":stats_observer_interface", + "../rtc_base:checks", "video:encoded_image", "video:video_frame", "video:video_rtp_headers", @@ -1049,7 +1050,10 @@ if (rtc_include_tests) { rtc_library("video_codec_stats_api") { visibility = [ "*" ] testonly = true - sources = [ "test/video_codec_stats.h" ] + sources = [ + "test/video_codec_stats.cc", + "test/video_codec_stats.h", + ] deps = [ "../api/numerics:numerics", "../api/units:data_rate", @@ -1113,7 +1117,7 @@ if (rtc_include_tests) { ] deps = [ ":video_codec_tester_api", - "../modules/video_coding:videocodec_test_impl", + "../modules/video_coding:video_codec_tester", ] } diff --git a/third_party/libwebrtc/api/array_view.h b/third_party/libwebrtc/api/array_view.h index 2d68f1650fbae..7e01959b01a4c 100644 --- a/third_party/libwebrtc/api/array_view.h +++ b/third_party/libwebrtc/api/array_view.h @@ -149,6 +149,10 @@ template { public: using value_type = T; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; using const_iterator = const T*; // Construct an ArrayView from a pointer and a length. diff --git a/third_party/libwebrtc/api/data_channel_interface.cc b/third_party/libwebrtc/api/data_channel_interface.cc index bddb9d1b0a411..970f53b4bd48e 100644 --- a/third_party/libwebrtc/api/data_channel_interface.cc +++ b/third_party/libwebrtc/api/data_channel_interface.cc @@ -10,6 +10,8 @@ #include "api/data_channel_interface.h" +#include "rtc_base/checks.h" + namespace webrtc { bool DataChannelInterface::ordered() const { @@ -44,4 +46,17 @@ uint64_t DataChannelInterface::MaxSendQueueSize() { return 16 * 1024 * 1024; // 16 MiB } +// TODO(tommi): Remove method once downstream implementations have been removed. +bool DataChannelInterface::Send(const DataBuffer& buffer) { + RTC_DCHECK_NOTREACHED(); + return false; +} + +// TODO(tommi): Remove implementation once method is pure virtual. +void DataChannelInterface::SendAsync( + DataBuffer buffer, + absl::AnyInvocable on_complete) { + RTC_DCHECK_NOTREACHED(); +} + } // namespace webrtc diff --git a/third_party/libwebrtc/api/data_channel_interface.h b/third_party/libwebrtc/api/data_channel_interface.h index 4f74918ff96c1..bf27c6c4f319b 100644 --- a/third_party/libwebrtc/api/data_channel_interface.h +++ b/third_party/libwebrtc/api/data_channel_interface.h @@ -19,6 +19,7 @@ #include +#include "absl/functional/any_invocable.h" #include "absl/types/optional.h" #include "api/priority.h" #include "api/rtc_error.h" @@ -100,6 +101,17 @@ class DataChannelObserver { // The data channel's buffered_amount has changed. virtual void OnBufferedAmountChange(uint64_t sent_data_size) {} + // Override this to get callbacks directly on the network thread. + // An implementation that does that must not block the network thread + // but rather only use the callback to trigger asynchronous processing + // elsewhere as a result of the notification. + // The default return value, `false`, means that notifications will be + // delivered on the signaling thread associated with the peerconnection + // instance. + // TODO(webrtc:11547): Eventually all DataChannelObserver implementations + // should be called on the network thread and this method removed. + virtual bool IsOkToCallOnTheNetworkThread() { return false; } + protected: virtual ~DataChannelObserver() = default; }; @@ -187,7 +199,20 @@ class RTC_EXPORT DataChannelInterface : public rtc::RefCountInterface { // Returns false if the data channel is not in open state or if the send // buffer is full. // TODO(webrtc:13289): Return an RTCError with information about the failure. - virtual bool Send(const DataBuffer& buffer) = 0; + // TODO(tommi): Remove this method once downstream implementations don't refer + // to it. + virtual bool Send(const DataBuffer& buffer); + + // Queues up an asynchronus send operation to run on a network thread. + // Once the operation has completed the `on_complete` callback is invoked, + // on the thread the send operation was done on. It's important that + // `on_complete` implementations do not block the current thread but rather + // post any expensive operations to other worker threads. + // TODO(tommi): Make pure virtual after updating mock class in Chromium. + // Deprecate `Send` in favor of this variant since the return value of `Send` + // is limiting for a fully async implementation (yet in practice is ignored). + virtual void SendAsync(DataBuffer buffer, + absl::AnyInvocable on_complete); // Amount of bytes that can be queued for sending on the data channel. // Those are bytes that have not yet been processed at the SCTP level. diff --git a/third_party/libwebrtc/api/field_trials_view.h b/third_party/libwebrtc/api/field_trials_view.h index 45e6f7899bd78..d8df84574d335 100644 --- a/third_party/libwebrtc/api/field_trials_view.h +++ b/third_party/libwebrtc/api/field_trials_view.h @@ -12,6 +12,7 @@ #include +#include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "rtc_base/system/rtc_export.h" @@ -32,18 +33,14 @@ class RTC_EXPORT FieldTrialsView { virtual std::string Lookup(absl::string_view key) const = 0; bool IsEnabled(absl::string_view key) const { - return Lookup(key).find("Enabled") == 0; + return absl::StartsWith(Lookup(key), "Enabled"); } bool IsDisabled(absl::string_view key) const { - return Lookup(key).find("Disabled") == 0; + return absl::StartsWith(Lookup(key), "Disabled"); } }; -// TODO(bugs.webrtc.org/10335): Remove once all migrated to -// api/field_trials_view.h -typedef FieldTrialsView WebRtcKeyValueConfig; - } // namespace webrtc #endif // API_FIELD_TRIALS_VIEW_H_ diff --git a/third_party/libwebrtc/api/frame_transformer_interface.h b/third_party/libwebrtc/api/frame_transformer_interface.h index 77242ee902b19..43fedd8595ecd 100644 --- a/third_party/libwebrtc/api/frame_transformer_interface.h +++ b/third_party/libwebrtc/api/frame_transformer_interface.h @@ -59,16 +59,9 @@ class TransformableVideoFrameInterface : public TransformableFrameInterface { virtual bool IsKeyFrame() const = 0; virtual const std::string& GetRid() const = 0; - // The returned const ref may become invalid due to later SetMetadata calls, - // or other modifications. Use Metadata() instead. - [[deprecated("Use Metadata() instead")]] virtual const VideoFrameMetadata& - GetMetadata() const = 0; - virtual VideoFrameMetadata Metadata() const = 0; - // TODO(https://crbug.com/webrtc/14709): Make pure virtual when Chromium MOCK - // has implemented this. - virtual void SetMetadata(const VideoFrameMetadata&) {} + virtual void SetMetadata(const VideoFrameMetadata&) = 0; }; // Extends the TransformableFrameInterface to expose audio-specific information. diff --git a/third_party/libwebrtc/api/legacy_stats_types.cc b/third_party/libwebrtc/api/legacy_stats_types.cc index e3b2144eddba7..278ac81a6e7ff 100644 --- a/third_party/libwebrtc/api/legacy_stats_types.cc +++ b/third_party/libwebrtc/api/legacy_stats_types.cc @@ -12,6 +12,8 @@ #include +#include + #include "absl/algorithm/container.h" #include "api/make_ref_counted.h" #include "rtc_base/checks.h" @@ -783,28 +785,28 @@ const StatsReport::Value* StatsReport::FindValue(StatsValueName name) const { StatsCollection::StatsCollection() {} StatsCollection::~StatsCollection() { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); for (auto* r : list_) delete r; } StatsCollection::const_iterator StatsCollection::begin() const { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); return list_.begin(); } StatsCollection::const_iterator StatsCollection::end() const { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); return list_.end(); } size_t StatsCollection::size() const { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); return list_.size(); } StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(Find(id) == nullptr); StatsReport* report = new StatsReport(id); list_.push_back(report); @@ -812,13 +814,13 @@ StatsReport* StatsCollection::InsertNew(const StatsReport::Id& id) { } StatsReport* StatsCollection::FindOrAddNew(const StatsReport::Id& id) { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); StatsReport* ret = Find(id); return ret ? ret : InsertNew(id); } StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(id.get()); Container::iterator it = absl::c_find_if( list_, @@ -832,10 +834,37 @@ StatsReport* StatsCollection::ReplaceOrAddNew(const StatsReport::Id& id) { return InsertNew(id); } +StatsCollection::Container StatsCollection::DetachCollection() { + RTC_DCHECK_RUN_ON(&thread_checker_); +#if RTC_DCHECK_IS_ON + for (auto* report : list_) + report->DetachSequenceCheckers(); +#endif + return std::move(list_); +} + +void StatsCollection::MergeCollection(Container collection) { + RTC_DCHECK_RUN_ON(&thread_checker_); + for (auto* report : collection) { +#if RTC_DCHECK_IS_ON + report->AttachSequenceCheckers(); +#endif + Container::iterator it = absl::c_find_if(list_, [&](const StatsReport* r) { + return r->id()->Equals(report->id()); + }); + if (it == list_.end()) { + list_.push_back(report); + } else { + delete *it; + *it = report; + } + } +} + // Looks for a report with the given `id`. If one is not found, null // will be returned. StatsReport* StatsCollection::Find(const StatsReport::Id& id) { - RTC_DCHECK(thread_checker_.IsCurrent()); + RTC_DCHECK_RUN_ON(&thread_checker_); Container::iterator it = absl::c_find_if( list_, [&id](const StatsReport* r) -> bool { return r->id()->Equals(id); }); diff --git a/third_party/libwebrtc/api/legacy_stats_types.h b/third_party/libwebrtc/api/legacy_stats_types.h index a62e014834f9c..e49cb6d6dd44e 100644 --- a/third_party/libwebrtc/api/legacy_stats_types.h +++ b/third_party/libwebrtc/api/legacy_stats_types.h @@ -344,8 +344,15 @@ class RTC_EXPORT StatsReport { // TODO(tommi): Move `name` and `display_name` out of the Value struct. const StatsValueName name; + protected: +#if RTC_DCHECK_IS_ON + friend class StatsReport; + void DetachSequenceChecker() { thread_checker_.Detach(); } + void AttachSequenceChecker() { RTC_DCHECK_RUN_ON(&thread_checker_); } +#endif + private: - webrtc::SequenceChecker thread_checker_; + webrtc::SequenceChecker thread_checker_{webrtc::SequenceChecker::kDetached}; mutable int ref_count_ RTC_GUARDED_BY(thread_checker_) = 0; const Type type_; @@ -403,6 +410,19 @@ class RTC_EXPORT StatsReport { const Value* FindValue(StatsValueName name) const; +#if RTC_DCHECK_IS_ON + void DetachSequenceCheckers() { + for (auto& v : values_) { + v.second->DetachSequenceChecker(); + } + } + void AttachSequenceCheckers() { + for (auto& v : values_) { + v.second->AttachSequenceChecker(); + } + } +#endif + private: // The unique identifier for this object. // This is used as a key for this report in ordered containers, @@ -441,13 +461,16 @@ class StatsCollection { StatsReport* FindOrAddNew(const StatsReport::Id& id); StatsReport* ReplaceOrAddNew(const StatsReport::Id& id); + Container DetachCollection(); + void MergeCollection(Container collection); + // Looks for a report with the given `id`. If one is not found, null // will be returned. StatsReport* Find(const StatsReport::Id& id); private: Container list_; - webrtc::SequenceChecker thread_checker_; + webrtc::SequenceChecker thread_checker_{SequenceChecker::kDetached}; }; } // namespace webrtc diff --git a/third_party/libwebrtc/api/neteq/neteq_controller.h b/third_party/libwebrtc/api/neteq/neteq_controller.h index 35112796f8bcc..a64a23374503d 100644 --- a/third_party/libwebrtc/api/neteq/neteq_controller.h +++ b/third_party/libwebrtc/api/neteq/neteq_controller.h @@ -81,7 +81,7 @@ class NetEqController { bool dtx_or_cng; size_t num_samples; size_t span_samples; - size_t span_samples_no_dtx; + size_t span_samples_wait_time; size_t num_packets; }; diff --git a/third_party/libwebrtc/api/notifier.h b/third_party/libwebrtc/api/notifier.h index fc2480e00ab00..64d5b22ad5487 100644 --- a/third_party/libwebrtc/api/notifier.h +++ b/third_party/libwebrtc/api/notifier.h @@ -25,7 +25,7 @@ namespace webrtc { template class Notifier : public T { public: - Notifier() { sequence_checker_.Detach(); } + Notifier() = default; virtual void RegisterObserver(ObserverInterface* observer) { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -60,7 +60,8 @@ class Notifier : public T { std::list observers_ RTC_GUARDED_BY(sequence_checker_); private: - RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ + SequenceChecker::kDetached}; }; } // namespace webrtc diff --git a/third_party/libwebrtc/api/peer_connection_interface.h b/third_party/libwebrtc/api/peer_connection_interface.h index 58e2d3396f2ae..6ce4650e5f9a7 100644 --- a/third_party/libwebrtc/api/peer_connection_interface.h +++ b/third_party/libwebrtc/api/peer_connection_interface.h @@ -1555,9 +1555,7 @@ class RTC_EXPORT PeerConnectionFactoryInterface virtual rtc::scoped_refptr CreateVideoTrack( rtc::scoped_refptr source, absl::string_view label) = 0; - // TODO(bugs.webrtc.org/15017): Deprecate this function once Chrome - // has been updated - it can't land as deprecated. - // ABSL_DEPRECATED("Use version with scoped_refptr") + ABSL_DEPRECATED("Use version with scoped_refptr") virtual rtc::scoped_refptr CreateVideoTrack( const std::string& label, VideoTrackSourceInterface* source) { diff --git a/third_party/libwebrtc/api/rtp_parameters.cc b/third_party/libwebrtc/api/rtp_parameters.cc index c1d12e5d8dc4b..cf8b3ad3dcab8 100644 --- a/third_party/libwebrtc/api/rtp_parameters.cc +++ b/third_party/libwebrtc/api/rtp_parameters.cc @@ -44,6 +44,9 @@ RtcpFeedback::RtcpFeedback(RtcpFeedbackType type, RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default; RtcpFeedback::~RtcpFeedback() = default; +RtpCodec::RtpCodec() = default; +RtpCodec::RtpCodec(const RtpCodec&) = default; +RtpCodec::~RtpCodec() = default; RtpCodecCapability::RtpCodecCapability() = default; RtpCodecCapability::~RtpCodecCapability() = default; diff --git a/third_party/libwebrtc/api/rtp_parameters.h b/third_party/libwebrtc/api/rtp_parameters.h index 1373527346710..e277e7d1accb2 100644 --- a/third_party/libwebrtc/api/rtp_parameters.h +++ b/third_party/libwebrtc/api/rtp_parameters.h @@ -122,12 +122,10 @@ struct RTC_EXPORT RtcpFeedback { bool operator!=(const RtcpFeedback& o) const { return !(*this == o); } }; -// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to -// RtpParameters. This represents the static capabilities of an endpoint's -// implementation of a codec. -struct RTC_EXPORT RtpCodecCapability { - RtpCodecCapability(); - ~RtpCodecCapability(); +struct RTC_EXPORT RtpCodec { + RtpCodec(); + RtpCodec(const RtpCodec&); + virtual ~RtpCodec(); // Build MIME "type/subtype" string from `name` and `kind`. std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; } @@ -138,25 +136,18 @@ struct RTC_EXPORT RtpCodecCapability { // The media type of this codec. Equivalent to MIME top-level type. cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO; - // Clock rate in Hertz. If unset, the codec is applicable to any clock rate. + // If unset, the implementation default is used. absl::optional clock_rate; - // Default payload type for this codec. Mainly needed for codecs that use - // that have statically assigned payload types. - absl::optional preferred_payload_type; - - // Maximum packetization time supported by an RtpReceiver for this codec. - // TODO(deadbeef): Not implemented. - absl::optional max_ptime; - - // Preferred packetization time for an RtpReceiver or RtpSender of this codec. - // TODO(deadbeef): Not implemented. - absl::optional ptime; - - // The number of audio channels supported. Unused for video codecs. + // The number of audio channels used. Unset for video codecs. If unset for + // audio, the implementation default is used. + // TODO(deadbeef): The "implementation default" part isn't fully implemented. + // Only defaults to 1, even though some codecs (such as opus) should really + // default to 2. absl::optional num_channels; - // Feedback mechanisms supported for this codec. + // Feedback mechanisms to be used for this codec. + // TODO(deadbeef): Not implemented with PeerConnection senders/receivers. std::vector rtcp_feedback; // Codec-specific parameters that must be signaled to the remote party. @@ -168,39 +159,31 @@ struct RTC_EXPORT RtpCodecCapability { // Boolean values are represented by the string "1". std::map parameters; - // Codec-specific parameters that may optionally be signaled to the remote - // party. - // TODO(deadbeef): Not implemented. - std::map options; - - // Maximum number of temporal layer extensions supported by this codec. - // For example, a value of 1 indicates that 2 total layers are supported. - // TODO(deadbeef): Not implemented. - int max_temporal_layer_extensions = 0; + bool operator==(const RtpCodec& o) const { + return name == o.name && kind == o.kind && clock_rate == o.clock_rate && + num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback && + parameters == o.parameters; + } + bool operator!=(const RtpCodec& o) const { return !(*this == o); } +}; - // Maximum number of spatial layer extensions supported by this codec. - // For example, a value of 1 indicates that 2 total layers are supported. - // TODO(deadbeef): Not implemented. - int max_spatial_layer_extensions = 0; +// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to +// RtpParameters. This represents the static capabilities of an endpoint's +// implementation of a codec. +struct RTC_EXPORT RtpCodecCapability : public RtpCodec { + RtpCodecCapability(); + virtual ~RtpCodecCapability(); - // Whether the implementation can send/receive SVC layers with distinct SSRCs. - // Always false for audio codecs. True for video codecs that support scalable - // video coding with MRST. - // TODO(deadbeef): Not implemented. - bool svc_multi_stream_support = false; + // Default payload type for this codec. Mainly needed for codecs that have + // statically assigned payload types. + absl::optional preferred_payload_type; - // https://w3c.github.io/webrtc-svc/#dom-rtcrtpcodeccapability-scalabilitymodes + // List of scalability modes supported by the video codec. absl::InlinedVector scalability_modes; bool operator==(const RtpCodecCapability& o) const { - return name == o.name && kind == o.kind && clock_rate == o.clock_rate && + return RtpCodec::operator==(o) && preferred_payload_type == o.preferred_payload_type && - max_ptime == o.max_ptime && ptime == o.ptime && - num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback && - parameters == o.parameters && options == o.options && - max_temporal_layer_extensions == o.max_temporal_layer_extensions && - max_spatial_layer_extensions == o.max_spatial_layer_extensions && - svc_multi_stream_support == o.svc_multi_stream_support && scalability_modes == o.scalability_modes; } bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); } @@ -554,63 +537,18 @@ struct RTC_EXPORT RtpEncodingParameters { } }; -struct RTC_EXPORT RtpCodecParameters { +struct RTC_EXPORT RtpCodecParameters : public RtpCodec { RtpCodecParameters(); RtpCodecParameters(const RtpCodecParameters&); - ~RtpCodecParameters(); - - // Build MIME "type/subtype" string from `name` and `kind`. - std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; } - - // Used to identify the codec. Equivalent to MIME subtype. - std::string name; - - // The media type of this codec. Equivalent to MIME top-level type. - cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO; + virtual ~RtpCodecParameters(); // Payload type used to identify this codec in RTP packets. // This must always be present, and must be unique across all codecs using // the same transport. int payload_type = 0; - // If unset, the implementation default is used. - absl::optional clock_rate; - - // The number of audio channels used. Unset for video codecs. If unset for - // audio, the implementation default is used. - // TODO(deadbeef): The "implementation default" part isn't fully implemented. - // Only defaults to 1, even though some codecs (such as opus) should really - // default to 2. - absl::optional num_channels; - - // The maximum packetization time to be used by an RtpSender. - // If `ptime` is also set, this will be ignored. - // TODO(deadbeef): Not implemented. - absl::optional max_ptime; - - // The packetization time to be used by an RtpSender. - // If unset, will use any time up to max_ptime. - // TODO(deadbeef): Not implemented. - absl::optional ptime; - - // Feedback mechanisms to be used for this codec. - // TODO(deadbeef): Not implemented with PeerConnection senders/receivers. - std::vector rtcp_feedback; - - // Codec-specific parameters that must be signaled to the remote party. - // - // Corresponds to "a=fmtp" parameters in SDP. - // - // Contrary to ORTC, these parameters are named using all lowercase strings. - // This helps make the mapping to SDP simpler, if an application is using SDP. - // Boolean values are represented by the string "1". - std::map parameters; - bool operator==(const RtpCodecParameters& o) const { - return name == o.name && kind == o.kind && payload_type == o.payload_type && - clock_rate == o.clock_rate && num_channels == o.num_channels && - max_ptime == o.max_ptime && ptime == o.ptime && - rtcp_feedback == o.rtcp_feedback && parameters == o.parameters; + return RtpCodec::operator==(o) && payload_type == o.payload_type; } bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); } }; diff --git a/third_party/libwebrtc/api/test/mock_data_channel.h b/third_party/libwebrtc/api/test/mock_data_channel.h index 38730eaa5162b..5d38ec13755c0 100644 --- a/third_party/libwebrtc/api/test/mock_data_channel.h +++ b/third_party/libwebrtc/api/test/mock_data_channel.h @@ -51,6 +51,11 @@ class MockDataChannelInterface MOCK_METHOD(uint64_t, buffered_amount, (), (const, override)); MOCK_METHOD(void, Close, (), (override)); MOCK_METHOD(bool, Send, (const DataBuffer& buffer), (override)); + MOCK_METHOD(void, + SendAsync, + (DataBuffer buffer, + absl::AnyInvocable on_complete), + (override)); protected: MockDataChannelInterface() = default; diff --git a/third_party/libwebrtc/api/test/mock_transformable_video_frame.h b/third_party/libwebrtc/api/test/mock_transformable_video_frame.h index 9d56a290eeaba..eab02d7e009cd 100644 --- a/third_party/libwebrtc/api/test/mock_transformable_video_frame.h +++ b/third_party/libwebrtc/api/test/mock_transformable_video_frame.h @@ -26,10 +26,6 @@ class MockTransformableVideoFrame MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override)); MOCK_METHOD(uint32_t, GetSsrc, (), (const, override)); MOCK_METHOD(bool, IsKeyFrame, (), (const, override)); - MOCK_METHOD(const webrtc::VideoFrameMetadata&, - GetMetadata, - (), - (const, override)); MOCK_METHOD(void, SetMetadata, (const webrtc::VideoFrameMetadata&), diff --git a/third_party/libwebrtc/api/test/pclf/media_configuration.h b/third_party/libwebrtc/api/test/pclf/media_configuration.h index 718a7b1723f97..5bcb308c837fe 100644 --- a/third_party/libwebrtc/api/test/pclf/media_configuration.h +++ b/third_party/libwebrtc/api/test/pclf/media_configuration.h @@ -375,19 +375,13 @@ struct VideoConfig { // Contains properties for audio in the call. struct AudioConfig { - enum Mode { - kGenerated, - kFile, - }; - AudioConfig() = default; explicit AudioConfig(absl::string_view stream_label); // Have to be unique among all specified configs for all peers in the call. // Will be auto generated if omitted. absl::optional stream_label; - Mode mode = kGenerated; - // Have to be specified only if mode = kFile + // If no file is specified an audio will be generated. absl::optional input_file_name; // If specified the input stream will be also copied to specified file. absl::optional input_dump_file_name; diff --git a/third_party/libwebrtc/api/test/video/test_video_track_source.cc b/third_party/libwebrtc/api/test/video/test_video_track_source.cc index c570a7a05f6f0..a7ec448a7fbbb 100644 --- a/third_party/libwebrtc/api/test/video/test_video_track_source.cc +++ b/third_party/libwebrtc/api/test/video/test_video_track_source.cc @@ -22,6 +22,7 @@ namespace test { TestVideoTrackSource::TestVideoTrackSource(bool remote) : state_(kInitializing), remote_(remote) { worker_thread_checker_.Detach(); + signaling_thread_checker_.Detach(); } VideoTrackSourceInterface::SourceState TestVideoTrackSource::state() const { diff --git a/third_party/libwebrtc/api/test/video/test_video_track_source.h b/third_party/libwebrtc/api/test/video/test_video_track_source.h index 4e2d138be0312..449228f81c907 100644 --- a/third_party/libwebrtc/api/test/video/test_video_track_source.h +++ b/third_party/libwebrtc/api/test/video/test_video_track_source.h @@ -62,6 +62,16 @@ class TestVideoTrackSource : public Notifier { virtual void SetScreencast(bool is_screencast) = 0; + // TODO(titovartem): make next 4 methods pure virtual. + virtual void SetEnableAdaptation(bool enable_adaptation) {} + + virtual int GetFrameWidth() const { return 0; } + virtual int GetFrameHeight() const { return 0; } + + virtual void OnOutputFormatRequest(int width, + int height, + const absl::optional& max_fps) {} + protected: virtual rtc::VideoSourceInterface* source() = 0; diff --git a/third_party/libwebrtc/api/test/video_codec_stats.cc b/third_party/libwebrtc/api/test/video_codec_stats.cc new file mode 100644 index 0000000000000..fb7226701e7e6 --- /dev/null +++ b/third_party/libwebrtc/api/test/video_codec_stats.cc @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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/test/video_codec_stats.h" + +namespace webrtc { +namespace test { + +void VideoCodecStats::Stream::LogMetrics( + MetricsLogger* logger, + std::string test_case_name, + std::map metadata) const { + logger->LogMetric("width", test_case_name, width, Unit::kCount, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("height", test_case_name, height, Unit::kCount, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric( + "frame_size_bytes", test_case_name, frame_size_bytes, Unit::kBytes, + webrtc::test::ImprovementDirection::kNeitherIsBetter, metadata); + + logger->LogMetric("keyframe", test_case_name, keyframe, Unit::kCount, + webrtc::test::ImprovementDirection::kSmallerIsBetter, + metadata); + + logger->LogMetric("qp", test_case_name, qp, Unit::kUnitless, + webrtc::test::ImprovementDirection::kSmallerIsBetter, + metadata); + + logger->LogMetric( + "encode_time_ms", test_case_name, encode_time_ms, Unit::kMilliseconds, + webrtc::test::ImprovementDirection::kSmallerIsBetter, metadata); + + logger->LogMetric( + "decode_time_ms", test_case_name, decode_time_ms, Unit::kMilliseconds, + webrtc::test::ImprovementDirection::kSmallerIsBetter, metadata); + + logger->LogMetric("target_bitrate_kbps", test_case_name, target_bitrate_kbps, + Unit::kKilobitsPerSecond, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("target_framerate_fps", test_case_name, + target_framerate_fps, Unit::kHertz, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("encoded_bitrate_kbps", test_case_name, + encoded_bitrate_kbps, Unit::kKilobitsPerSecond, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("encoded_framerate_fps", test_case_name, + encoded_framerate_fps, Unit::kHertz, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("bitrate_mismatch_pct", test_case_name, + bitrate_mismatch_pct, Unit::kPercent, + webrtc::test::ImprovementDirection::kSmallerIsBetter, + metadata); + + logger->LogMetric("framerate_mismatch_pct", test_case_name, + framerate_mismatch_pct, Unit::kPercent, + webrtc::test::ImprovementDirection::kSmallerIsBetter, + metadata); + + logger->LogMetric("transmission_time_ms", test_case_name, + transmission_time_ms, Unit::kMilliseconds, + webrtc::test::ImprovementDirection::kSmallerIsBetter, + metadata); + + logger->LogMetric("psnr_y_db", test_case_name, psnr.y, Unit::kUnitless, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("psnr_u_db", test_case_name, psnr.u, Unit::kUnitless, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); + + logger->LogMetric("psnr_v_db", test_case_name, psnr.v, Unit::kUnitless, + webrtc::test::ImprovementDirection::kBiggerIsBetter, + metadata); +} + +} // namespace test +} // namespace webrtc diff --git a/third_party/libwebrtc/api/test/video_codec_stats.h b/third_party/libwebrtc/api/test/video_codec_stats.h index 1be1d8e8b804f..80f82878485f2 100644 --- a/third_party/libwebrtc/api/test/video_codec_stats.h +++ b/third_party/libwebrtc/api/test/video_codec_stats.h @@ -96,6 +96,11 @@ class VideoCodecStats { SamplesStatsCounter u; SamplesStatsCounter v; } psnr; + + // Logs `Stream` metrics to provided `MetricsLogger`. + void LogMetrics(MetricsLogger* logger, + std::string test_case_name, + std::map metadata = {}) const; }; virtual ~VideoCodecStats() = default; @@ -107,13 +112,6 @@ class VideoCodecStats { // Returns video statistics aggregated for given `frames`. virtual Stream Aggregate(const std::vector& frames) const = 0; - - // Logs `Stream` metrics to provided `MetricsLogger`. - virtual void LogMetrics( - MetricsLogger* logger, - const Stream& stream, - std::string test_case_name, - std::map metadata = {}) const = 0; }; } // namespace test diff --git a/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h b/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h index f20ae3efc9bb7..d21bc6c5f70ad 100644 --- a/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h +++ b/third_party/libwebrtc/api/test/video_quality_analyzer_interface.h @@ -21,6 +21,7 @@ #include "api/video/encoded_image.h" #include "api/video/video_frame.h" #include "api/video_codecs/video_encoder.h" +#include "rtc_base/checks.h" namespace webrtc { @@ -150,13 +151,15 @@ class VideoQualityAnalyzerInterface // call. virtual void UnregisterParticipantInCall(absl::string_view peer_name) {} - // Informs analyzer that peer `receiver_peer_name` shouldn't receive all - // streams from sender `sender_peer_name`. + // Informs analyzer that peer `receiver_peer_name` should not receive any + // stream from sender `sender_peer_name`. + // This method is a no-op if the sender or the receiver does not exist. virtual void OnPauseAllStreamsFrom(absl::string_view sender_peer_name, absl::string_view receiver_peer_name) {} // Informs analyzer that peer `receiver_peer_name` is expected to receive all // streams from `sender_peer_name`. + // This method is a no-op if the sender or the receiver does not exist. virtual void OnResumeAllStreamsFrom(absl::string_view sender_peer_name, absl::string_view receiver_peer_name) {} @@ -168,6 +171,13 @@ class VideoQualityAnalyzerInterface // frame ids space wraps around, then stream label for frame id may change. // It will crash, if the specified `frame_id` wasn't captured. virtual std::string GetStreamLabel(uint16_t frame_id) = 0; + + // Returns the sender peer name of the last stream where this frame was + // captured. The sender for this frame id may change when the frame ids wrap + // around. Also it will crash, if the specified `frame_id` wasn't captured. + virtual std::string GetSenderPeerName(uint16_t frame_id) const { + RTC_CHECK(false) << "Not implemented."; + } }; } // namespace webrtc diff --git a/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc index 16f2e69fa0f0e..252ae210b6b99 100644 --- a/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc +++ b/third_party/libwebrtc/api/video/builtin_video_bitrate_allocator_factory.cc @@ -31,18 +31,14 @@ class BuiltinVideoBitrateAllocatorFactory std::unique_ptr CreateVideoBitrateAllocator( const VideoCodec& codec) override { - switch (codec.codecType) { - case kVideoCodecAV1: - case kVideoCodecVP9: - // TODO(https://crbug.com/webrtc/14884): Update SvcRateAllocator to - // support simulcast and use it for VP9/AV1 simulcast as well. - if (codec.IsSinglecastOrAllNonFirstLayersInactive()) { - return std::make_unique(codec); - } - ABSL_FALLTHROUGH_INTENDED; - default: - return std::make_unique(codec); + // TODO(https://crbug.com/webrtc/14884): Update SvcRateAllocator to + // support simulcast and use it for VP9/AV1 simulcast as well. + if ((codec.codecType == kVideoCodecAV1 || + codec.codecType == kVideoCodecVP9) && + codec.numberOfSimulcastStreams <= 1) { + return std::make_unique(codec); } + return std::make_unique(codec); } }; diff --git a/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc b/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc index e9d7052501b65..1cc2b582743a4 100644 --- a/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc +++ b/third_party/libwebrtc/api/video_codecs/test/video_decoder_factory_template_tests.cc @@ -114,8 +114,8 @@ TEST(VideoDecoderFactoryTemplate, OpenH264) { TEST(VideoDecoderFactoryTemplate, Dav1d) { VideoDecoderFactoryTemplate factory; auto formats = factory.GetSupportedFormats(); - EXPECT_THAT(formats.size(), 1); - EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1")); + EXPECT_THAT(formats, Not(IsEmpty())); + EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "AV1"))); EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr)); } diff --git a/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc b/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc index 4c3d0cd24e2b5..91b02aa90517e 100644 --- a/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc +++ b/third_party/libwebrtc/api/video_codecs/test/video_encoder_factory_template_tests.cc @@ -22,8 +22,9 @@ using ::testing::Each; using ::testing::Eq; using ::testing::Field; using ::testing::IsEmpty; -using ::testing::Ne; +using ::testing::IsNull; using ::testing::Not; +using ::testing::NotNull; using ::testing::UnorderedElementsAre; namespace webrtc { @@ -68,8 +69,8 @@ struct BarEncoderTemplateAdapter { TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) { VideoEncoderFactoryTemplate factory; EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp)); - EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr)); - EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull()); + EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull()); } TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) { @@ -97,11 +98,11 @@ TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) { factory; EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp)); - EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr)); - EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), Ne(nullptr)); - EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), Ne(nullptr)); - EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr)); - EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), Eq(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull()); + EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), NotNull()); + EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), NotNull()); + EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull()); + EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), NotNull()); } TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) { @@ -131,7 +132,7 @@ TEST(VideoEncoderFactoryTemplate, LibvpxVp8) { EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8")); EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes, Contains(ScalabilityMode::kL1T3))); - EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull()); } TEST(VideoEncoderFactoryTemplate, LibvpxVp9) { @@ -141,7 +142,7 @@ TEST(VideoEncoderFactoryTemplate, LibvpxVp9) { EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9"))); EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes, Contains(ScalabilityMode::kL3T3_KEY)))); - EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull()); } // TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build @@ -154,7 +155,7 @@ TEST(VideoEncoderFactoryTemplate, OpenH264) { EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264"))); EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes, Contains(ScalabilityMode::kL1T3)))); - EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull()); } #endif // defined(WEBRTC_USE_H264) @@ -165,7 +166,7 @@ TEST(VideoEncoderFactoryTemplate, LibaomAv1) { EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1")); EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes, Contains(ScalabilityMode::kL3T3_KEY))); - EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr)); + EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull()); } } // namespace diff --git a/third_party/libwebrtc/api/video_codecs/video_codec.cc b/third_party/libwebrtc/api/video_codecs/video_codec.cc index f21c1a340171e..c6122d3f6ac30 100644 --- a/third_party/libwebrtc/api/video_codecs/video_codec.cc +++ b/third_party/libwebrtc/api/video_codecs/video_codec.cc @@ -152,13 +152,4 @@ void VideoCodec::SetFrameDropEnabled(bool enabled) { frame_drop_enabled_ = enabled; } -bool VideoCodec::IsSinglecastOrAllNonFirstLayersInactive() const { - for (int i = 1; i < numberOfSimulcastStreams; ++i) { - if (simulcastStream[i].active) { - return false; - } - } - return true; -} - } // namespace webrtc diff --git a/third_party/libwebrtc/api/video_codecs/video_codec.h b/third_party/libwebrtc/api/video_codecs/video_codec.h index a4d19ca613377..10bceda0d23b0 100644 --- a/third_party/libwebrtc/api/video_codecs/video_codec.h +++ b/third_party/libwebrtc/api/video_codecs/video_codec.h @@ -130,8 +130,6 @@ class RTC_EXPORT VideoCodec { bool GetFrameDropEnabled() const; void SetFrameDropEnabled(bool enabled); - bool IsSinglecastOrAllNonFirstLayersInactive() const; - // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; diff --git a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h index 6d80cadf835ce..bffbdc43d33cd 100644 --- a/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h +++ b/third_party/libwebrtc/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h @@ -14,13 +14,17 @@ #include #include +#include "api/video_codecs/av1_profile.h" #include "api/video_codecs/sdp_video_format.h" #include "modules/video_coding/codecs/av1/dav1d_decoder.h" namespace webrtc { struct Dav1dDecoderTemplateAdapter { static std::vector SupportedFormats() { - return {SdpVideoFormat("AV1")}; + return {SdpVideoFormat("AV1"), + SdpVideoFormat( + "AV1", {{kAV1FmtpProfile, + AV1ProfileToString(AV1Profile::kProfile1).data()}})}; } static std::unique_ptr CreateDecoder( diff --git a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h index 643096dbbba52..10212ac816480 100644 --- a/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h +++ b/third_party/libwebrtc/api/video_codecs/video_encoder_factory_template.h @@ -17,6 +17,7 @@ #include "absl/algorithm/container.h" #include "api/array_view.h" +#include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" #include "modules/video_coding/svc/scalability_mode_util.h" @@ -51,7 +52,16 @@ class VideoEncoderFactoryTemplate : public VideoEncoderFactory { std::unique_ptr CreateVideoEncoder( const SdpVideoFormat& format) override { - return CreateVideoEncoderInternal(format); + // We fuzzy match the specified format for both valid and not so valid + // reasons. The valid reason is that there are many standardized codec + // specific fmtp parameters that have not been implemented, and in those + // cases we should not fail to instantiate an encoder just because we don't + // recognize the parameter. The not so valid reason is that we have started + // adding parameters completely unrelated to the SDP to the SdpVideoFormat. + // TODO(bugs.webrtc.org/13868): Remove FuzzyMatchSdpVideoFormat + absl::optional matched = + FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format); + return CreateVideoEncoderInternal(matched.value_or(format)); } CodecSupport QueryCodecSupport( diff --git a/third_party/libwebrtc/audio/BUILD.gn b/third_party/libwebrtc/audio/BUILD.gn index d3f2d87c6928c..654cdbce0eafd 100644 --- a/third_party/libwebrtc/audio/BUILD.gn +++ b/third_party/libwebrtc/audio/BUILD.gn @@ -86,7 +86,6 @@ rtc_library("audio") { "../modules/pacing", "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", - "../modules/utility:utility", "../rtc_base:audio_format_to_string", "../rtc_base:buffer", "../rtc_base:checks", @@ -135,9 +134,12 @@ if (rtc_include_tests) { "../api/task_queue", "../call:fake_network", "../call:simulated_network", + "../modules/audio_device:audio_device_api", + "../modules/audio_device:test_audio_device_module", "../system_wrappers", "../test:test_common", "../test:test_support", + "../test:video_test_constants", ] } @@ -196,7 +198,6 @@ if (rtc_include_tests) { "../modules/pacing", "../modules/rtp_rtcp:mock_rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", - "../modules/utility:utility", "../rtc_base:checks", "../rtc_base:gunit_helpers", "../rtc_base:macromagic", @@ -213,9 +214,11 @@ if (rtc_include_tests) { "../test:mock_transformable_frame", "../test:mock_transport", "../test:rtp_test_utils", + "../test:run_loop", "../test:scoped_key_value_config", "../test:test_common", "../test:test_support", + "../test:video_test_constants", "../test/time_controller:time_controller", "utility:utility_tests", "//testing/gtest", @@ -277,6 +280,7 @@ if (rtc_include_tests) { "../test:test_common", "../test:test_main", "../test:test_support", + "../test:video_test_constants", "../test/pc/e2e:network_quality_metrics_reporter", "//testing/gtest", ] diff --git a/third_party/libwebrtc/audio/audio_receive_stream.cc b/third_party/libwebrtc/audio/audio_receive_stream.cc index d76c1856d82fb..8a3ac93a36a35 100644 --- a/third_party/libwebrtc/audio/audio_receive_stream.cc +++ b/third_party/libwebrtc/audio/audio_receive_stream.cc @@ -115,8 +115,6 @@ AudioReceiveStreamImpl::AudioReceiveStreamImpl( RTC_DCHECK(audio_state_); RTC_DCHECK(channel_receive_); - packet_sequence_checker_.Detach(); - RTC_DCHECK(packet_router); // Configure bandwidth estimation. channel_receive_->RegisterReceiverCongestionControlObjects(packet_router); @@ -264,10 +262,10 @@ webrtc::AudioReceiveStreamInterface::Stats AudioReceiveStreamImpl::GetStats( return stats; } - stats.payload_bytes_rcvd = call_stats.payload_bytes_rcvd; - stats.header_and_padding_bytes_rcvd = - call_stats.header_and_padding_bytes_rcvd; - stats.packets_rcvd = call_stats.packetsReceived; + stats.payload_bytes_received = call_stats.payload_bytes_received; + stats.header_and_padding_bytes_received = + call_stats.header_and_padding_bytes_received; + stats.packets_received = call_stats.packetsReceived; stats.packets_lost = call_stats.cumulativeLost; stats.nacks_sent = call_stats.nacks_sent; stats.capture_start_ntp_time_ms = call_stats.capture_start_ntp_time_ms_; @@ -377,7 +375,8 @@ AudioReceiveStreamImpl::GetAudioFrameWithInfo(int sample_rate_hz, AudioFrame* audio_frame) { AudioMixer::Source::AudioFrameInfo audio_frame_info = channel_receive_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame); - if (audio_frame_info != AudioMixer::Source::AudioFrameInfo::kError) { + if (audio_frame_info != AudioMixer::Source::AudioFrameInfo::kError && + !audio_frame->packet_infos_.empty()) { source_tracker_.OnFrameDelivered(audio_frame->packet_infos_); } return audio_frame_info; diff --git a/third_party/libwebrtc/audio/audio_receive_stream.h b/third_party/libwebrtc/audio/audio_receive_stream.h index b0df0a7f0dd1c..db49631638b58 100644 --- a/third_party/libwebrtc/audio/audio_receive_stream.h +++ b/third_party/libwebrtc/audio/audio_receive_stream.h @@ -154,7 +154,8 @@ class AudioReceiveStreamImpl final : public webrtc::AudioReceiveStreamInterface, // thread, but still serves as a mechanism of grouping together concepts // that belong to the network thread. Once the packets are fully delivered // on the network thread, this comment will be deleted. - RTC_NO_UNIQUE_ADDRESS SequenceChecker packet_sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker packet_sequence_checker_{ + SequenceChecker::kDetached}; webrtc::AudioReceiveStreamInterface::Config config_; rtc::scoped_refptr audio_state_; SourceTracker source_tracker_; diff --git a/third_party/libwebrtc/audio/audio_receive_stream_unittest.cc b/third_party/libwebrtc/audio/audio_receive_stream_unittest.cc index e10e4c391097b..451d5f9b91ac1 100644 --- a/third_party/libwebrtc/audio/audio_receive_stream_unittest.cc +++ b/third_party/libwebrtc/audio/audio_receive_stream_unittest.cc @@ -29,6 +29,7 @@ #include "test/gtest.h" #include "test/mock_audio_decoder_factory.h" #include "test/mock_transport.h" +#include "test/run_loop.h" namespace webrtc { namespace test { @@ -215,6 +216,7 @@ TEST(AudioReceiveStreamTest, ConfigToString) { } TEST(AudioReceiveStreamTest, ConstructDestruct) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); @@ -223,6 +225,7 @@ TEST(AudioReceiveStreamTest, ConstructDestruct) { } TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); @@ -236,6 +239,7 @@ TEST(AudioReceiveStreamTest, ReceiveRtcpPacket) { } TEST(AudioReceiveStreamTest, GetStats) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); @@ -243,11 +247,11 @@ TEST(AudioReceiveStreamTest, GetStats) { AudioReceiveStreamInterface::Stats stats = recv_stream->GetStats(/*get_and_clear_legacy_stats=*/true); EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc); - EXPECT_EQ(kCallStats.payload_bytes_rcvd, stats.payload_bytes_rcvd); - EXPECT_EQ(kCallStats.header_and_padding_bytes_rcvd, - stats.header_and_padding_bytes_rcvd); + EXPECT_EQ(kCallStats.payload_bytes_received, stats.payload_bytes_received); + EXPECT_EQ(kCallStats.header_and_padding_bytes_received, + stats.header_and_padding_bytes_received); EXPECT_EQ(static_cast(kCallStats.packetsReceived), - stats.packets_rcvd); + stats.packets_received); EXPECT_EQ(kCallStats.cumulativeLost, stats.packets_lost); EXPECT_EQ(kReceiveCodec.second.name, stats.codec_name); EXPECT_EQ( @@ -321,6 +325,7 @@ TEST(AudioReceiveStreamTest, GetStats) { } TEST(AudioReceiveStreamTest, SetGain) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); @@ -332,6 +337,7 @@ TEST(AudioReceiveStreamTest, SetGain) { } TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper1(use_null_audio_processing); ConfigHelper helper2(helper1.audio_mixer(), use_null_audio_processing); @@ -366,6 +372,7 @@ TEST(AudioReceiveStreamTest, StreamsShouldBeAddedToMixerOnceOnStart) { } TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); @@ -393,6 +400,7 @@ TEST(AudioReceiveStreamTest, ReconfigureWithUpdatedConfig) { } TEST(AudioReceiveStreamTest, ReconfigureWithFrameDecryptor) { + test::RunLoop loop; for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(use_null_audio_processing); auto recv_stream = helper.CreateAudioReceiveStream(); diff --git a/third_party/libwebrtc/audio/audio_send_stream.cc b/third_party/libwebrtc/audio/audio_send_stream.cc index 20af3f7722696..9330932e3c51b 100644 --- a/third_party/libwebrtc/audio/audio_send_stream.cc +++ b/third_party/libwebrtc/audio/audio_send_stream.cc @@ -147,7 +147,6 @@ AudioSendStream::AudioSendStream( const FieldTrialsView& field_trials) : clock_(clock), field_trials_(field_trials), - rtp_transport_queue_(rtp_transport->GetWorkerQueue()), allocate_audio_without_feedback_( field_trials_.IsEnabled("WebRTC-Audio-ABWENoTWCC")), enable_audio_alr_probing_( @@ -164,7 +163,6 @@ AudioSendStream::AudioSendStream( rtp_rtcp_module_(channel_send_->GetRtpRtcp()), suspended_rtp_state_(suspended_rtp_state) { RTC_LOG(LS_INFO) << "AudioSendStream: " << config.rtp.ssrc; - RTC_DCHECK(rtp_transport_queue_); RTC_DCHECK(audio_state_); RTC_DCHECK(channel_send_); RTC_DCHECK(bitrate_allocator_); @@ -182,10 +180,6 @@ AudioSendStream::~AudioSendStream() { RTC_LOG(LS_INFO) << "~AudioSendStream: " << config_.rtp.ssrc; RTC_DCHECK(!sending_); channel_send_->ResetSenderCongestionControlObjects(); - - // Blocking call to synchronize state with worker queue to ensure that there - // are no pending tasks left that keeps references to audio. - rtp_transport_queue_->RunSynchronous([] {}); } const webrtc::AudioSendStream::Config& AudioSendStream::GetConfig() const { @@ -492,7 +486,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( stats.report_block_datas = std::move(call_stats.report_block_datas); - stats.nacks_rcvd = call_stats.nacks_rcvd; + stats.nacks_received = call_stats.nacks_received; return stats; } @@ -511,7 +505,7 @@ void AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { } uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + 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 @@ -826,6 +820,7 @@ void AudioSendStream::ReconfigureBitrateObserver( } void AudioSendStream::ConfigureBitrateObserver() { + RTC_DCHECK_RUN_ON(&worker_thread_checker_); // This either updates the current observer or adds a new observer. // TODO(srte): Add overhead compensation here. auto constraints = GetMinMaxBitrateConstraints(); @@ -847,30 +842,24 @@ void AudioSendStream::ConfigureBitrateObserver() { priority_bitrate += min_overhead; } - if (allocation_settings_.priority_bitrate_raw) + if (allocation_settings_.priority_bitrate_raw) { priority_bitrate = *allocation_settings_.priority_bitrate_raw; + } + + bitrate_allocator_->AddObserver( + this, + MediaStreamAllocationConfig{ + constraints->min.bps(), constraints->max.bps(), 0, + priority_bitrate.bps(), true, + allocation_settings_.bitrate_priority.value_or( + config_.bitrate_priority)}); - rtp_transport_queue_->RunOrPost([this, constraints, priority_bitrate, - config_bitrate_priority = - config_.bitrate_priority] { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); - bitrate_allocator_->AddObserver( - this, - MediaStreamAllocationConfig{ - constraints->min.bps(), constraints->max.bps(), - 0, priority_bitrate.bps(), true, - allocation_settings_.bitrate_priority.value_or( - config_bitrate_priority)}); - }); registered_with_allocator_ = true; } void AudioSendStream::RemoveBitrateObserver() { registered_with_allocator_ = false; - rtp_transport_queue_->RunSynchronous([this] { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); - bitrate_allocator_->RemoveObserver(this); - }); + bitrate_allocator_->RemoveObserver(this); } absl::optional @@ -931,10 +920,7 @@ void AudioSendStream::UpdateCachedTargetAudioBitrateConstraints() { if (!new_constraints.has_value()) { return; } - rtp_transport_queue_->RunOrPost([this, new_constraints]() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); - cached_constraints_ = new_constraints; - }); + cached_constraints_ = new_constraints; } } // namespace internal diff --git a/third_party/libwebrtc/audio/audio_send_stream.h b/third_party/libwebrtc/audio/audio_send_stream.h index 42be43afb9302..6cda9c3d52149 100644 --- a/third_party/libwebrtc/audio/audio_send_stream.h +++ b/third_party/libwebrtc/audio/audio_send_stream.h @@ -25,7 +25,6 @@ #include "call/audio_state.h" #include "call/bitrate_allocator.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" -#include "modules/utility/maybe_worker_thread.h" #include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/race_checker.h" #include "rtc_base/synchronization/mutex.h" @@ -173,7 +172,6 @@ class AudioSendStream final : public webrtc::AudioSendStream, SequenceChecker worker_thread_checker_; rtc::RaceChecker audio_capture_race_checker_; - MaybeWorkerThread* rtp_transport_queue_; const bool allocate_audio_without_feedback_; const bool force_no_audio_feedback_ = allocate_audio_without_feedback_; @@ -196,10 +194,10 @@ class AudioSendStream final : public webrtc::AudioSendStream, webrtc::voe::AudioLevel audio_level_ RTC_GUARDED_BY(audio_level_lock_); BitrateAllocatorInterface* const bitrate_allocator_ - RTC_GUARDED_BY(rtp_transport_queue_); - // Constrains cached to be accessed from `rtp_transport_queue_`. + RTC_GUARDED_BY(worker_thread_checker_); absl::optional - cached_constraints_ RTC_GUARDED_BY(rtp_transport_queue_) = absl::nullopt; + cached_constraints_ RTC_GUARDED_BY(worker_thread_checker_) = + absl::nullopt; RtpTransportControllerSendInterface* const rtp_transport_; RtpRtcpInterface* const rtp_rtcp_module_; diff --git a/third_party/libwebrtc/audio/audio_send_stream_tests.cc b/third_party/libwebrtc/audio/audio_send_stream_tests.cc index 2ec7229bfbc8f..1337a01286c3f 100644 --- a/third_party/libwebrtc/audio/audio_send_stream_tests.cc +++ b/third_party/libwebrtc/audio/audio_send_stream_tests.cc @@ -19,6 +19,7 @@ #include "test/field_trial.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" namespace webrtc { namespace test { @@ -31,7 +32,7 @@ enum : int { // The first valid value is 1. class AudioSendTest : public SendTest { public: - AudioSendTest() : SendTest(CallTest::kDefaultTimeout) {} + AudioSendTest() : SendTest(VideoTestConstants::kDefaultTimeout) {} size_t GetNumVideoStreams() const override { return 0; } size_t GetNumAudioStreams() const override { return 1; } diff --git a/third_party/libwebrtc/audio/audio_send_stream_unittest.cc b/third_party/libwebrtc/audio/audio_send_stream_unittest.cc index a81b40cbe7d3a..a6450d3e89c65 100644 --- a/third_party/libwebrtc/audio/audio_send_stream_unittest.cc +++ b/third_party/libwebrtc/audio/audio_send_stream_unittest.cc @@ -30,7 +30,6 @@ #include "modules/audio_processing/include/mock_audio_processing.h" #include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h" #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" -#include "modules/utility/maybe_worker_thread.h" #include "system_wrappers/include/clock.h" #include "test/gtest.h" #include "test/mock_audio_encoder.h" @@ -155,9 +154,6 @@ struct ConfigHelper { ? nullptr : rtc::make_ref_counted>()), bitrate_allocator_(&limit_observer_), - worker_queue_(field_trials, - "ConfigHelper_worker_queue", - time_controller_.GetTaskQueueFactory()), audio_encoder_(nullptr) { using ::testing::Invoke; @@ -188,8 +184,6 @@ struct ConfigHelper { } std::unique_ptr CreateAudioSendStream() { - EXPECT_CALL(rtp_transport_, GetWorkerQueue()) - .WillRepeatedly(Return(&worker_queue_)); return std::unique_ptr( new internal::AudioSendStream( time_controller_.GetClock(), stream_config_, audio_state_, @@ -319,8 +313,6 @@ struct ConfigHelper { } } - MaybeWorkerThread* worker() { return &worker_queue_; } - test::ScopedKeyValueConfig field_trials; private: @@ -336,9 +328,6 @@ struct ConfigHelper { ::testing::NiceMock rtp_rtcp_; ::testing::NiceMock limit_observer_; BitrateAllocator bitrate_allocator_; - // `worker_queue` is defined last to ensure all pending tasks are cancelled - // and deleted before any other members. - MaybeWorkerThread worker_queue_; std::unique_ptr audio_encoder_; }; @@ -636,8 +625,7 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { update.packet_loss_ratio = 0; update.round_trip_time = TimeDelta::Millis(50); update.bwe_period = TimeDelta::Millis(6000); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -653,8 +641,7 @@ TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) { BitrateAllocationUpdate update; update.target_bitrate = DataRate::BitsPerSec(helper.config().max_bitrate_bps - 5000); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -670,8 +657,7 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) { Eq(DataRate::KilobitsPerSec(6))))); BitrateAllocationUpdate update; update.target_bitrate = DataRate::KilobitsPerSec(1); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -687,8 +673,7 @@ TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) { Eq(DataRate::KilobitsPerSec(64))))); BitrateAllocationUpdate update; update.target_bitrate = DataRate::KilobitsPerSec(128); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -708,8 +693,7 @@ TEST(AudioSendStreamTest, SSBweWithOverhead) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; update.target_bitrate = bitrate; - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -729,8 +713,7 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; update.target_bitrate = DataRate::KilobitsPerSec(1); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -750,8 +733,7 @@ TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) { &BitrateAllocationUpdate::target_bitrate, Eq(bitrate)))); BitrateAllocationUpdate update; update.target_bitrate = DataRate::KilobitsPerSec(128); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -769,8 +751,7 @@ TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { update.packet_loss_ratio = 0; update.round_trip_time = TimeDelta::Millis(50); update.bwe_period = TimeDelta::Millis(5000); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); } } @@ -872,8 +853,7 @@ TEST(AudioSendStreamTest, AudioOverheadChanged) { DataRate::BitsPerSec(helper.config().max_bitrate_bps) + kMaxOverheadRate; EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); EXPECT_EQ(audio_overhead_per_packet_bytes, send_stream->TestOnlyGetPerPacketOverheadBytes()); @@ -881,8 +861,7 @@ TEST(AudioSendStreamTest, AudioOverheadChanged) { EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead) .WillRepeatedly(Return(audio_overhead_per_packet_bytes + 20)); EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); EXPECT_EQ(audio_overhead_per_packet_bytes + 20, send_stream->TestOnlyGetPerPacketOverheadBytes()); @@ -906,8 +885,7 @@ TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) { DataRate::BitsPerSec(helper.config().max_bitrate_bps) + kMaxOverheadRate; EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation); - helper.worker()->RunSynchronous( - [&] { send_stream->OnBitrateUpdated(update); }); + send_stream->OnBitrateUpdated(update); EXPECT_EQ( transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes, diff --git a/third_party/libwebrtc/audio/audio_state.cc b/third_party/libwebrtc/audio/audio_state.cc index 76ff152eeae24..6f20e7b128bb3 100644 --- a/third_party/libwebrtc/audio/audio_state.cc +++ b/third_party/libwebrtc/audio/audio_state.cc @@ -32,7 +32,6 @@ AudioState::AudioState(const AudioState::Config& config) audio_transport_(config_.audio_mixer.get(), config_.audio_processing.get(), config_.async_audio_processing_factory.get()) { - process_thread_checker_.Detach(); RTC_DCHECK(config_.audio_mixer); RTC_DCHECK(config_.audio_device_module); } diff --git a/third_party/libwebrtc/audio/audio_state.h b/third_party/libwebrtc/audio/audio_state.h index 6c2b7aa453767..88aaaa3697a13 100644 --- a/third_party/libwebrtc/audio/audio_state.h +++ b/third_party/libwebrtc/audio/audio_state.h @@ -65,7 +65,7 @@ class AudioState : public webrtc::AudioState { void UpdateNullAudioPollerState() RTC_RUN_ON(&thread_checker_); SequenceChecker thread_checker_; - SequenceChecker process_thread_checker_; + SequenceChecker process_thread_checker_{SequenceChecker::kDetached}; const webrtc::AudioState::Config config_; bool recording_enabled_ = true; bool playout_enabled_ = true; diff --git a/third_party/libwebrtc/audio/channel_receive.cc b/third_party/libwebrtc/audio/channel_receive.cc index 9697ed0d1a208..9a1abd5bfa46f 100644 --- a/third_party/libwebrtc/audio/channel_receive.cc +++ b/third_party/libwebrtc/audio/channel_receive.cc @@ -829,17 +829,17 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const { // Data counters. if (statistician) { - stats.payload_bytes_rcvd = rtp_stats.packet_counter.payload_bytes; + stats.payload_bytes_received = rtp_stats.packet_counter.payload_bytes; - stats.header_and_padding_bytes_rcvd = + stats.header_and_padding_bytes_received = rtp_stats.packet_counter.header_bytes + rtp_stats.packet_counter.padding_bytes; stats.packetsReceived = rtp_stats.packet_counter.packets; stats.last_packet_received_timestamp_ms = rtp_stats.last_packet_received_timestamp_ms; } else { - stats.payload_bytes_rcvd = 0; - stats.header_and_padding_bytes_rcvd = 0; + stats.payload_bytes_received = 0; + stats.header_and_padding_bytes_received = 0; stats.packetsReceived = 0; stats.last_packet_received_timestamp_ms = absl::nullopt; } diff --git a/third_party/libwebrtc/audio/channel_receive.h b/third_party/libwebrtc/audio/channel_receive.h index 5fbfb8a240574..37bf903394e2e 100644 --- a/third_party/libwebrtc/audio/channel_receive.h +++ b/third_party/libwebrtc/audio/channel_receive.h @@ -54,8 +54,8 @@ class RtpRtcp; struct CallReceiveStatistics { int cumulativeLost; unsigned int jitterSamples; - int64_t payload_bytes_rcvd = 0; - int64_t header_and_padding_bytes_rcvd = 0; + int64_t payload_bytes_received = 0; + int64_t header_and_padding_bytes_received = 0; int packetsReceived; uint32_t nacks_sent = 0; // The capture NTP time (in local timebase) of the first played out audio diff --git a/third_party/libwebrtc/audio/channel_send.cc b/third_party/libwebrtc/audio/channel_send.cc index 785a9e5d09e26..8a402ca467d52 100644 --- a/third_party/libwebrtc/audio/channel_send.cc +++ b/third_party/libwebrtc/audio/channel_send.cc @@ -817,7 +817,7 @@ CallSendStatistics ChannelSend::GetRTCPStatistics() const { { MutexLock lock(&rtcp_counter_mutex_); - stats.nacks_rcvd = rtcp_packet_type_counter_.nack_packets; + stats.nacks_received = rtcp_packet_type_counter_.nack_packets; } return stats; @@ -928,7 +928,7 @@ int64_t ChannelSend::GetRTT() const { // We don't know in advance the remote ssrc used by the other end's receiver // reports, so use the first report block for the RTT. - return report_blocks.front().last_rtt_ms(); + return report_blocks.front().last_rtt().ms(); } void ChannelSend::SetFrameEncryptor( diff --git a/third_party/libwebrtc/audio/channel_send.h b/third_party/libwebrtc/audio/channel_send.h index 9b3969161c0a7..47361882d518f 100644 --- a/third_party/libwebrtc/audio/channel_send.h +++ b/third_party/libwebrtc/audio/channel_send.h @@ -49,7 +49,7 @@ struct CallSendStatistics { // ReportBlockData represents the latest Report Block that was received for // that pair. std::vector report_block_datas; - uint32_t nacks_rcvd; + uint32_t nacks_received; }; // See section 6.4.2 in http://www.ietf.org/rfc/rfc3550.txt for details. diff --git a/third_party/libwebrtc/audio/test/audio_end_to_end_test.cc b/third_party/libwebrtc/audio/test/audio_end_to_end_test.cc index b7dfdb89f6643..b1e2712f60c7e 100644 --- a/third_party/libwebrtc/audio/test/audio_end_to_end_test.cc +++ b/third_party/libwebrtc/audio/test/audio_end_to_end_test.cc @@ -16,20 +16,21 @@ #include "api/task_queue/task_queue_base.h" #include "call/fake_network_pipe.h" #include "call/simulated_network.h" +#include "modules/audio_device/include/test_audio_device.h" #include "system_wrappers/include/sleep.h" #include "test/gtest.h" +#include "test/video_test_constants.h" namespace webrtc { namespace test { namespace { -// Wait half a second between stopping sending and stopping receiving audio. -constexpr int kExtraRecordTimeMs = 500; constexpr int kSampleRate = 48000; + } // namespace AudioEndToEndTest::AudioEndToEndTest() - : EndToEndTest(CallTest::kDefaultTimeout) {} + : EndToEndTest(VideoTestConstants::kDefaultTimeout) {} size_t AudioEndToEndTest::GetNumVideoStreams() const { return 0; @@ -54,8 +55,8 @@ AudioEndToEndTest::CreateRenderer() { } void AudioEndToEndTest::OnFakeAudioDevicesCreated( - TestAudioDeviceModule* send_audio_device, - TestAudioDeviceModule* recv_audio_device) { + AudioDeviceModule* send_audio_device, + AudioDeviceModule* recv_audio_device) { send_audio_device_ = send_audio_device; } @@ -66,7 +67,7 @@ void AudioEndToEndTest::ModifyAudioConfigs( const webrtc::SdpAudioFormat kDefaultFormat("opus", 48000, 2, {{"stereo", "1"}}); send_config->send_codec_spec = AudioSendStream::Config::SendCodecSpec( - test::CallTest::kAudioSendPayloadType, kDefaultFormat); + test::VideoTestConstants::kAudioSendPayloadType, kDefaultFormat); send_config->min_bitrate_bps = 32000; send_config->max_bitrate_bps = 32000; } @@ -81,11 +82,5 @@ void AudioEndToEndTest::OnAudioStreamsCreated( receive_stream_ = receive_streams[0]; } -void AudioEndToEndTest::PerformTest() { - // Wait until the input audio file is done... - send_audio_device_->WaitForRecordingEnd(); - // and some extra time to account for network delay. - SleepMs(GetSendTransportConfig().queue_delay_ms + kExtraRecordTimeMs); -} } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/audio/test/audio_end_to_end_test.h b/third_party/libwebrtc/audio/test/audio_end_to_end_test.h index 607fe692bef3a..d326b790ff3c1 100644 --- a/third_party/libwebrtc/audio/test/audio_end_to_end_test.h +++ b/third_party/libwebrtc/audio/test/audio_end_to_end_test.h @@ -16,6 +16,8 @@ #include "api/task_queue/task_queue_base.h" #include "api/test/simulated_network.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_device/include/test_audio_device.h" #include "test/call_test.h" namespace webrtc { @@ -26,7 +28,7 @@ class AudioEndToEndTest : public test::EndToEndTest { AudioEndToEndTest(); protected: - TestAudioDeviceModule* send_audio_device() { return send_audio_device_; } + AudioDeviceModule* send_audio_device() { return send_audio_device_; } const AudioSendStream* send_stream() const { return send_stream_; } const AudioReceiveStreamInterface* receive_stream() const { return receive_stream_; @@ -39,9 +41,8 @@ class AudioEndToEndTest : public test::EndToEndTest { std::unique_ptr CreateCapturer() override; std::unique_ptr CreateRenderer() override; - void OnFakeAudioDevicesCreated( - TestAudioDeviceModule* send_audio_device, - TestAudioDeviceModule* recv_audio_device) override; + void OnFakeAudioDevicesCreated(AudioDeviceModule* send_audio_device, + AudioDeviceModule* recv_audio_device) override; void ModifyAudioConfigs(AudioSendStream::Config* send_config, std::vector* @@ -50,10 +51,8 @@ class AudioEndToEndTest : public test::EndToEndTest { const std::vector& receive_streams) override; - void PerformTest() override; - private: - TestAudioDeviceModule* send_audio_device_ = nullptr; + AudioDeviceModule* send_audio_device_ = nullptr; AudioSendStream* send_stream_ = nullptr; AudioReceiveStreamInterface* receive_stream_ = nullptr; }; diff --git a/third_party/libwebrtc/audio/test/audio_stats_test.cc b/third_party/libwebrtc/audio/test/audio_stats_test.cc index 1c81432574118..e8521cfe99746 100644 --- a/third_party/libwebrtc/audio/test/audio_stats_test.cc +++ b/third_party/libwebrtc/audio/test/audio_stats_test.cc @@ -17,6 +17,9 @@ namespace webrtc { namespace test { namespace { +// Wait half a second between stopping sending and stopping receiving audio. +constexpr int kExtraRecordTimeMs = 500; + bool IsNear(int reference, int v) { // Margin is 10%. const int error = reference / 10 + 1; @@ -41,7 +44,8 @@ class NoLossTest : public AudioEndToEndTest { void PerformTest() override { SleepMs(kTestDurationMs); send_audio_device()->StopRecording(); - AudioEndToEndTest::PerformTest(); + // and some extra time to account for network delay. + SleepMs(GetSendTransportConfig().queue_delay_ms + kExtraRecordTimeMs); } void OnStreamsStopped() override { @@ -66,8 +70,8 @@ class NoLossTest : public AudioEndToEndTest { AudioReceiveStreamInterface::Stats recv_stats = receive_stream()->GetStats(/*get_and_clear_legacy_stats=*/true); - EXPECT_PRED2(IsNear, kBytesSent, recv_stats.payload_bytes_rcvd); - EXPECT_PRED2(IsNear, kPacketsSent, recv_stats.packets_rcvd); + EXPECT_PRED2(IsNear, kBytesSent, recv_stats.payload_bytes_received); + EXPECT_PRED2(IsNear, kPacketsSent, recv_stats.packets_received); EXPECT_EQ(0, recv_stats.packets_lost); EXPECT_EQ("opus", send_stats.codec_name); // recv_stats.jitter_ms diff --git a/third_party/libwebrtc/audio/test/low_bandwidth_audio_test.cc b/third_party/libwebrtc/audio/test/low_bandwidth_audio_test.cc index f385eb9dccdc2..903f482e7175e 100644 --- a/third_party/libwebrtc/audio/test/low_bandwidth_audio_test.cc +++ b/third_party/libwebrtc/audio/test/low_bandwidth_audio_test.cc @@ -14,6 +14,7 @@ #include "audio/test/audio_end_to_end_test.h" #include "system_wrappers/include/sleep.h" #include "test/testsupport/file_utils.h" +#include "test/video_test_constants.h" ABSL_DECLARE_FLAG(int, sample_rate_hz); ABSL_DECLARE_FLAG(bool, quick); @@ -57,7 +58,8 @@ class AudioQualityTest : public AudioEndToEndTest { // Let the recording run for a small amount of time to check if it works. SleepMs(1000); } else { - AudioEndToEndTest::PerformTest(); + // Sleep for whole audio duration which is 5.4 seconds. + SleepMs(5400); } } @@ -77,7 +79,7 @@ class Mobile2GNetworkTest : public AudioQualityTest { std::vector* receive_configs) override { send_config->send_codec_spec = AudioSendStream::Config::SendCodecSpec( - test::CallTest::kAudioSendPayloadType, + test::VideoTestConstants::kAudioSendPayloadType, {"OPUS", 48000, 2, diff --git a/third_party/libwebrtc/audio/test/nack_test.cc b/third_party/libwebrtc/audio/test/nack_test.cc index c4bfe8306f154..b36adf899168a 100644 --- a/third_party/libwebrtc/audio/test/nack_test.cc +++ b/third_party/libwebrtc/audio/test/nack_test.cc @@ -48,7 +48,7 @@ TEST_F(NackTest, ShouldNackInLossyNetwork) { EXPECT_GT(recv_stats.nacks_sent, 0U); AudioSendStream::Stats send_stats = send_stream()->GetStats(); EXPECT_GT(send_stats.retransmitted_packets_sent, 0U); - EXPECT_GT(send_stats.nacks_rcvd, 0U); + EXPECT_GT(send_stats.nacks_received, 0U); } } test; diff --git a/third_party/libwebrtc/audio/test/pc_low_bandwidth_audio_test.cc b/third_party/libwebrtc/audio/test/pc_low_bandwidth_audio_test.cc index 8b733d578d1b6..083aedf76e1ff 100644 --- a/third_party/libwebrtc/audio/test/pc_low_bandwidth_audio_test.cc +++ b/third_party/libwebrtc/audio/test/pc_low_bandwidth_audio_test.cc @@ -134,7 +134,6 @@ TEST(PCLowBandwidthAudioTest, PCGoodNetworkHighBitrate) { [](PeerConfigurer* alice) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = AudioInputFile(); audio.output_dump_file_name = AudioOutputFile(); audio.sampling_frequency_in_hz = absl::GetFlag(FLAGS_sample_rate_hz); @@ -160,7 +159,6 @@ TEST(PCLowBandwidthAudioTest, PC40kbpsNetwork) { [](PeerConfigurer* alice) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = AudioInputFile(); audio.output_dump_file_name = AudioOutputFile(); audio.sampling_frequency_in_hz = absl::GetFlag(FLAGS_sample_rate_hz); diff --git a/third_party/libwebrtc/audio/voip/audio_ingress.cc b/third_party/libwebrtc/audio/voip/audio_ingress.cc index d2e7c2396af2c..d2ea58da91eff 100644 --- a/third_party/libwebrtc/audio/voip/audio_ingress.cc +++ b/third_party/libwebrtc/audio/voip/audio_ingress.cc @@ -275,13 +275,10 @@ ChannelStatistics AudioIngress::GetChannelStatistics() { static_cast(rtcp_report.jitter) / clockrate_hz; } if (block_data.has_rtt()) { - remote_stat.round_trip_time = - static_cast(block_data.last_rtt_ms()) / - rtc::kNumMillisecsPerSec; + remote_stat.round_trip_time = block_data.last_rtt().seconds(); } remote_stat.last_report_received_timestamp_ms = - block_data.report_block_timestamp_utc_us() / - rtc::kNumMicrosecsPerMillisec; + block_data.report_block_timestamp_utc().ms(); channel_stats.remote_rtcp = remote_stat; // Receive only channel won't send any RTP packets. diff --git a/third_party/libwebrtc/call/BUILD.gn b/third_party/libwebrtc/call/BUILD.gn index 2bc7aaec925e2..20e9241a8303b 100644 --- a/third_party/libwebrtc/call/BUILD.gn +++ b/third_party/libwebrtc/call/BUILD.gn @@ -210,7 +210,6 @@ rtc_library("rtp_sender") { "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", "../modules/rtp_rtcp:rtp_video_header", - "../modules/utility:utility", "../modules/video_coding:chain_diff_calculator", "../modules/video_coding:codec_globals_headers", "../modules/video_coding:frame_dependencies_calculator", @@ -333,6 +332,7 @@ rtc_library("call") { "../rtc_base:rtc_task_queue", "../rtc_base:safe_minmax", "../rtc_base:stringutils", + "../rtc_base:threading", "../rtc_base:timeutils", "../rtc_base/experiments:field_trial_parser", "../rtc_base/network:sent_packet", @@ -504,6 +504,7 @@ if (rtc_include_tests) { "../api/task_queue:default_task_queue_factory", "../api/test/video:function_video_factory", "../api/transport:field_trial_based_config", + "../api/units:timestamp", "../api/video:builtin_video_bitrate_allocator_factory", "../api/video:video_frame", "../api/video:video_rtp_headers", @@ -538,13 +539,14 @@ if (rtc_include_tests) { "../test:explicit_key_value_config", "../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", "../test:test_common", "../test:test_support", - "../test:video_test_common", + "../test:video_test_constants", "../test/scenario", "../test/time_controller:time_controller", "../video", @@ -592,7 +594,7 @@ if (rtc_include_tests) { "../media:rtc_simulcast_encoder_adapter", "../modules/audio_coding", "../modules/audio_device", - "../modules/audio_device:audio_device_impl", + "../modules/audio_device:test_audio_device_module", "../modules/audio_mixer:audio_mixer_impl", "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", @@ -614,10 +616,12 @@ if (rtc_include_tests) { "../test:fake_video_codecs", "../test:field_trial", "../test:fileutils", + "../test:frame_generator_capturer", "../test:null_transport", "../test:test_common", "../test:test_support", "../test:video_test_common", + "../test:video_test_constants", "../video", "../video/config:encoder_config", "//testing/gtest", diff --git a/third_party/libwebrtc/call/audio_receive_stream.h b/third_party/libwebrtc/call/audio_receive_stream.h index c21a6b3f1f708..acafff9e3272d 100644 --- a/third_party/libwebrtc/call/audio_receive_stream.h +++ b/third_party/libwebrtc/call/audio_receive_stream.h @@ -34,9 +34,9 @@ class AudioReceiveStreamInterface : public MediaReceiveStreamInterface { Stats(); ~Stats(); uint32_t remote_ssrc = 0; - int64_t payload_bytes_rcvd = 0; - int64_t header_and_padding_bytes_rcvd = 0; - uint32_t packets_rcvd = 0; + int64_t payload_bytes_received = 0; + int64_t header_and_padding_bytes_received = 0; + uint32_t packets_received = 0; uint64_t fec_packets_received = 0; uint64_t fec_packets_discarded = 0; int32_t packets_lost = 0; diff --git a/third_party/libwebrtc/call/audio_send_stream.h b/third_party/libwebrtc/call/audio_send_stream.h index 187ec65ed8d33..5f4f871bf039f 100644 --- a/third_party/libwebrtc/call/audio_send_stream.h +++ b/third_party/libwebrtc/call/audio_send_stream.h @@ -74,7 +74,7 @@ class AudioSendStream : public AudioSender { // per-pair the ReportBlockData represents the latest Report Block that was // received for that pair. std::vector report_block_datas; - uint32_t nacks_rcvd = 0; + uint32_t nacks_received = 0; }; struct Config { diff --git a/third_party/libwebrtc/call/bitrate_estimator_tests.cc b/third_party/libwebrtc/call/bitrate_estimator_tests.cc index 58605b94c7588..f44cdfd5099b0 100644 --- a/third_party/libwebrtc/call/bitrate_estimator_tests.cc +++ b/third_party/libwebrtc/call/bitrate_estimator_tests.cc @@ -29,6 +29,7 @@ #include "test/fake_encoder.h" #include "test/frame_generator_capturer.h" #include "test/gtest.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -80,7 +81,9 @@ class LogObserver { } } - bool Wait() { return done_.Wait(test::CallTest::kDefaultTimeout); } + bool Wait() { + return done_.Wait(test::VideoTestConstants::kDefaultTimeout); + } void PushExpectedLogLine(absl::string_view expected_log_line) { MutexLock lock(&mutex_); @@ -122,13 +125,15 @@ class BitrateEstimatorTest : public test::CallTest { /*observer=*/nullptr); VideoSendStream::Config video_send_config(send_transport_.get()); - video_send_config.rtp.ssrcs.push_back(kVideoSendSsrcs[0]); + video_send_config.rtp.ssrcs.push_back( + test::VideoTestConstants::kVideoSendSsrcs[0]); video_send_config.encoder_settings.encoder_factory = &fake_encoder_factory_; video_send_config.encoder_settings.bitrate_allocator_factory = bitrate_allocator_factory_.get(); video_send_config.rtp.payload_name = "FAKE"; - video_send_config.rtp.payload_type = kFakeVideoSendPayloadType; + video_send_config.rtp.payload_type = + test::VideoTestConstants::kFakeVideoSendPayloadType; SetVideoSendConfig(video_send_config); VideoEncoderConfig video_encoder_config; test::FillEncoderConfiguration(kVideoCodecVP8, 1, &video_encoder_config); @@ -138,7 +143,8 @@ class BitrateEstimatorTest : public test::CallTest { VideoReceiveStreamInterface::Config(receive_transport_.get()); // receive_config_.decoders will be set by every stream separately. receive_config_.rtp.remote_ssrc = GetVideoSendConfig()->rtp.ssrcs[0]; - receive_config_.rtp.local_ssrc = kReceiverLocalVideoSsrc; + receive_config_.rtp.local_ssrc = + test::VideoTestConstants::kReceiverLocalVideoSsrc; }); } @@ -173,9 +179,12 @@ class BitrateEstimatorTest : public test::CallTest { frame_generator_capturer_ = std::make_unique( test->clock_, - test::CreateSquareFrameGenerator(kDefaultWidth, kDefaultHeight, - absl::nullopt, absl::nullopt), - kDefaultFramerate, *test->task_queue_factory_); + test::CreateSquareFrameGenerator( + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight, absl::nullopt, + absl::nullopt), + test::VideoTestConstants::kDefaultFramerate, + *test->task_queue_factory_); frame_generator_capturer_->Init(); send_stream_->SetSource(frame_generator_capturer_.get(), DegradationPreference::MAINTAIN_FRAMERATE); diff --git a/third_party/libwebrtc/call/call.cc b/third_party/libwebrtc/call/call.cc index 85dbd2adfa56b..0421a21ee3b15 100644 --- a/third_party/libwebrtc/call/call.cc +++ b/third_party/libwebrtc/call/call.cc @@ -1402,16 +1402,10 @@ void Call::DeliverRtpPacket( packet.set_arrival_time(Timestamp::Micros(packet_time_us)); } - // We might get RTP keep-alive packets in accordance with RFC6263 section 4.6. - // These are empty (zero length payload) RTP packets with an unsignaled - // payload type. - const bool is_keep_alive_packet = packet.payload_size() == 0; - RTC_DCHECK(media_type == MediaType::AUDIO || media_type == MediaType::VIDEO || - is_keep_alive_packet); NotifyBweOfReceivedPacket(packet, media_type); + event_log_->Log(std::make_unique(packet)); if (media_type != MediaType::AUDIO && media_type != MediaType::VIDEO) { - RTC_DCHECK(is_keep_alive_packet); return; } @@ -1432,7 +1426,6 @@ void Call::DeliverRtpPacket( return; } } - event_log_->Log(std::make_unique(packet)); // RateCounters expect input parameter as int, save it as int, // instead of converting each time it is passed to RateCounter::Add below. diff --git a/third_party/libwebrtc/call/call_perf_tests.cc b/third_party/libwebrtc/call/call_perf_tests.cc index f90d8ec2525cb..ce98d079570de 100644 --- a/third_party/libwebrtc/call/call_perf_tests.cc +++ b/third_party/libwebrtc/call/call_perf_tests.cc @@ -31,6 +31,7 @@ #include "media/engine/internal_encoder_factory.h" #include "media/engine/simulcast_encoder_adapter.h" #include "modules/audio_coding/include/audio_coding_module.h" +#include "modules/audio_device/include/audio_device.h" #include "modules/audio_device/include/test_audio_device.h" #include "modules/audio_mixer/audio_mixer_impl.h" #include "modules/rtp_rtcp/source/rtp_packet.h" @@ -53,6 +54,7 @@ #include "test/rtp_rtcp_observer.h" #include "test/testsupport/file_utils.h" #include "test/video_encoder_proxy_factory.h" +#include "test/video_test_constants.h" #include "video/config/video_encoder_config.h" #include "video/transport_adapter.h" @@ -115,7 +117,7 @@ class VideoRtcpAndSyncObserver : public test::RtpRtcpObserver, explicit VideoRtcpAndSyncObserver(TaskQueueBase* task_queue, Clock* clock, absl::string_view test_label) - : test::RtpRtcpObserver(CallPerfTest::kLongTimeout), + : test::RtpRtcpObserver(test::VideoTestConstants::kLongTimeout), clock_(clock), test_label_(test_label), creation_time_ms_(clock_->TimeInMilliseconds()), @@ -206,7 +208,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, SendTask(task_queue(), [&]() { metrics::Reset(); - rtc::scoped_refptr fake_audio_device = + rtc::scoped_refptr fake_audio_device = TestAudioDeviceModule::Create( task_queue_factory_.get(), TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000), @@ -273,18 +275,23 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, audio_send_config.rtp.ssrc = kAudioSendSsrc; // TODO(bugs.webrtc.org/14683): Let the tests fail with invalid config. audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec( - kAudioSendPayloadType, {"OPUS", 48000, 2}); + test::VideoTestConstants::kAudioSendPayloadType, {"OPUS", 48000, 2}); audio_send_config.min_bitrate_bps = 6000; audio_send_config.max_bitrate_bps = 510000; audio_send_config.encoder_factory = CreateBuiltinAudioEncoderFactory(); audio_send_stream = sender_call_->CreateAudioSendStream(audio_send_config); - GetVideoSendConfig()->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + GetVideoSendConfig()->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; if (fec == FecMode::kOn) { - GetVideoSendConfig()->rtp.ulpfec.red_payload_type = kRedPayloadType; - GetVideoSendConfig()->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; - video_receive_configs_[0].rtp.red_payload_type = kRedPayloadType; - video_receive_configs_[0].rtp.ulpfec_payload_type = kUlpfecPayloadType; + GetVideoSendConfig()->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + GetVideoSendConfig()->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; + video_receive_configs_[0].rtp.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + video_receive_configs_[0].rtp.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; } video_receive_configs_[0].rtp.nack.rtp_history_ms = 1000; video_receive_configs_[0].renderer = observer.get(); @@ -297,7 +304,7 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, audio_recv_config.sync_group = kSyncGroup; audio_recv_config.decoder_factory = audio_decoder_factory_; audio_recv_config.decoder_map = { - {kAudioSendPayloadType, {"OPUS", 48000, 2}}}; + {test::VideoTestConstants::kAudioSendPayloadType, {"OPUS", 48000, 2}}}; if (create_first == CreateOrder::kAudioFirst) { audio_receive_stream = @@ -311,9 +318,11 @@ void CallPerfTest::TestAudioVideoSync(FecMode fec, EXPECT_EQ(1u, video_receive_streams_.size()); observer->set_receive_stream(video_receive_streams_[0]); drifting_clock = std::make_unique(clock_, video_ntp_speed); - CreateFrameGeneratorCapturerWithDrift(drifting_clock.get(), video_rtp_speed, - kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturerWithDrift( + drifting_clock.get(), video_rtp_speed, + test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); Start(); @@ -404,7 +413,7 @@ void CallPerfTest::TestCaptureNtpTime( int threshold_ms, int start_time_ms, int run_time_ms) - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), net_config_(net_config), clock_(Clock::GetRealTimeClock()), threshold_ms_(threshold_ms), @@ -557,7 +566,9 @@ TEST_F(CallPerfTest, ReceivesCpuOveruseAndUnderuse) { class LoadObserver : public test::SendTest, public test::FrameGeneratorCapturer::SinkWantsObserver { public: - LoadObserver() : SendTest(kLongTimeout), test_phase_(TestPhase::kInit) {} + LoadObserver() + : SendTest(test::VideoTestConstants::kLongTimeout), + test_phase_(TestPhase::kInit) {} void OnFrameGeneratorCapturerCreated( test::FrameGeneratorCapturer* frame_generator_capturer) override { @@ -666,7 +677,7 @@ void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) { public: explicit BitrateObserver(bool using_min_transmit_bitrate, TaskQueueBase* task_queue) - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), send_stream_(nullptr), converged_(false), pad_to_min_bitrate_(using_min_transmit_bitrate), @@ -793,7 +804,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { class BitrateObserver : public test::EndToEndTest, public test::FakeEncoder { public: explicit BitrateObserver(TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), encoder_inits_(0), last_set_bitrate_kbps_(0), @@ -817,11 +828,11 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { : kInitialBitrateKbps - kInitialBitrateOverheadKpbs; EXPECT_EQ(expected_bitrate, config->startBitrate) << "Encoder not initialized at expected bitrate."; - EXPECT_EQ(kDefaultWidth, config->width); - EXPECT_EQ(kDefaultHeight, config->height); + EXPECT_EQ(test::VideoTestConstants::kDefaultWidth, config->width); + EXPECT_EQ(test::VideoTestConstants::kDefaultHeight, config->height); } else if (encoder_inits_ == 2) { - EXPECT_EQ(2 * kDefaultWidth, config->width); - EXPECT_EQ(2 * kDefaultHeight, config->height); + EXPECT_EQ(2 * test::VideoTestConstants::kDefaultWidth, config->width); + EXPECT_EQ(2 * test::VideoTestConstants::kDefaultHeight, config->height); EXPECT_GE(last_set_bitrate_kbps_, kReconfigureThresholdKbps); EXPECT_GT(config->startBitrate, kReconfigureThresholdKbps) << "Encoder reconfigured with bitrate too far away from last set."; @@ -870,9 +881,12 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { } void PerformTest() override { - ASSERT_TRUE(time_to_reconfigure_.Wait(kDefaultTimeout)) + ASSERT_TRUE( + time_to_reconfigure_.Wait(test::VideoTestConstants::kDefaultTimeout)) << "Timed out before receiving an initial high bitrate."; - frame_generator_->ChangeResolution(kDefaultWidth * 2, kDefaultHeight * 2); + frame_generator_->ChangeResolution( + test::VideoTestConstants::kDefaultWidth * 2, + test::VideoTestConstants::kDefaultHeight * 2); SendTask(task_queue_, [&]() { send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy()); }); @@ -1056,7 +1070,7 @@ void CallPerfTest::TestEncodeFramerate(VideoEncoderFactory* encoder_factory, absl::string_view payload_name, const std::vector& max_framerates, TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), clock_(Clock::GetRealTimeClock()), encoder_factory_(encoder_factory), payload_name_(payload_name), @@ -1095,7 +1109,8 @@ void CallPerfTest::TestEncodeFramerate(VideoEncoderFactory* encoder_factory, VideoEncoderConfig* encoder_config) override { send_config->encoder_settings.encoder_factory = encoder_factory_; send_config->rtp.payload_name = payload_name_; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; encoder_config->video_format.name = payload_name_; encoder_config->codec_type = PayloadStringToCodecType(payload_name_); encoder_config->max_bitrate_bps = kMaxBitrate.bps(); diff --git a/third_party/libwebrtc/call/call_unittest.cc b/third_party/libwebrtc/call/call_unittest.cc index 5db3f5902bd55..944006d8f22a8 100644 --- a/third_party/libwebrtc/call/call_unittest.cc +++ b/third_party/libwebrtc/call/call_unittest.cc @@ -18,11 +18,13 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/media_types.h" #include "api/rtc_event_log/rtc_event_log.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/test/mock_audio_mixer.h" #include "api/test/video/function_video_encoder_factory.h" #include "api/transport/field_trial_based_config.h" +#include "api/units/timestamp.h" #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "audio/audio_receive_stream.h" #include "audio/audio_send_stream.h" @@ -42,6 +44,7 @@ namespace { using ::testing::_; using ::testing::Contains; +using ::testing::MockFunction; using ::testing::NiceMock; using ::testing::StrictMock; @@ -323,6 +326,45 @@ TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) { } } +TEST(CallTest, + DeliverRtpPacketOfTypeAudioTriggerOnUndemuxablePacketHandlerIfNotDemuxed) { + CallHelper call(/*use_null_audio_processing=*/false); + MockFunction + un_demuxable_packet_handler; + + RtpPacketReceived packet; + packet.set_arrival_time(Timestamp::Millis(1)); + EXPECT_CALL(un_demuxable_packet_handler, Call); + call->Receiver()->DeliverRtpPacket( + MediaType::AUDIO, packet, un_demuxable_packet_handler.AsStdFunction()); +} + +TEST(CallTest, + DeliverRtpPacketOfTypeVideoTriggerOnUndemuxablePacketHandlerIfNotDemuxed) { + CallHelper call(/*use_null_audio_processing=*/false); + MockFunction + un_demuxable_packet_handler; + + RtpPacketReceived packet; + packet.set_arrival_time(Timestamp::Millis(1)); + EXPECT_CALL(un_demuxable_packet_handler, Call); + call->Receiver()->DeliverRtpPacket( + MediaType::VIDEO, packet, un_demuxable_packet_handler.AsStdFunction()); +} + +TEST(CallTest, + DeliverRtpPacketOfTypeAnyDoesNotTriggerOnUndemuxablePacketHandler) { + CallHelper call(/*use_null_audio_processing=*/false); + MockFunction + un_demuxable_packet_handler; + + RtpPacketReceived packet; + packet.set_arrival_time(Timestamp::Millis(1)); + EXPECT_CALL(un_demuxable_packet_handler, Call).Times(0); + call->Receiver()->DeliverRtpPacket( + MediaType::ANY, packet, un_demuxable_packet_handler.AsStdFunction()); +} + TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) { constexpr uint32_t kSSRC = 12345; for (bool use_null_audio_processing : {false, true}) { diff --git a/third_party/libwebrtc/call/degraded_call.cc b/third_party/libwebrtc/call/degraded_call.cc index 99c32296c3068..114be134ab431 100644 --- a/third_party/libwebrtc/call/degraded_call.cc +++ b/third_party/libwebrtc/call/degraded_call.cc @@ -16,7 +16,7 @@ #include "absl/strings/string_view.h" #include "api/sequence_checker.h" #include "modules/rtp_rtcp/source/rtp_util.h" -#include "rtc_base/event.h" +#include "rtc_base/thread.h" namespace webrtc { @@ -174,13 +174,10 @@ DegradedCall::~DegradedCall() { // Otherwise, when the `DegradedCall` object is destroyed but // `SetNotAlive` has not yet been called, // another Closure guarded by `call_alive_` may be called. - rtc::Event event; - call_->network_thread()->PostTask( - [flag = std::move(call_alive_), &event]() mutable { - flag->SetNotAlive(); - event.Set(); - }); - event.Wait(rtc::Event::kForever); + // TODO(https://crbug.com/webrtc/12649): Remove this block-invoke. + static_cast(call_->network_thread()) + ->BlockingCall( + [flag = std::move(call_alive_)]() mutable { flag->SetNotAlive(); }); } AudioSendStream* DegradedCall::CreateAudioSendStream( diff --git a/third_party/libwebrtc/call/packet_receiver.h b/third_party/libwebrtc/call/packet_receiver.h index c7f55ac46c0ee..cdcf7bfc7393f 100644 --- a/third_party/libwebrtc/call/packet_receiver.h +++ b/third_party/libwebrtc/call/packet_receiver.h @@ -28,7 +28,9 @@ class PacketReceiver { using OnUndemuxablePacketHandler = absl::AnyInvocable; - // Demux RTP packets. Must be called on the worker thread. + // Must be called on the worker thread. + // If `media_type` is not Audio or Video, packets may be used for BWE + // calculations but are not demuxed. virtual void DeliverRtpPacket( MediaType media_type, RtpPacketReceived packet, diff --git a/third_party/libwebrtc/call/rampup_tests.cc b/third_party/libwebrtc/call/rampup_tests.cc index 3c89670a9fbd5..8ddce83a2e734 100644 --- a/third_party/libwebrtc/call/rampup_tests.cc +++ b/third_party/libwebrtc/call/rampup_tests.cc @@ -30,6 +30,7 @@ #include "rtc_base/time_utils.h" #include "test/encoder_settings.h" #include "test/gtest.h" +#include "test/video_test_constants.h" ABSL_FLAG(std::string, ramp_dump_name, @@ -69,7 +70,7 @@ RampUpTester::RampUpTester(size_t num_video_streams, bool red, bool report_perf_stats, TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), clock_(Clock::GetRealTimeClock()), num_video_streams_(num_video_streams), num_audio_streams_(num_audio_streams), @@ -163,8 +164,8 @@ void RampUpTester::ModifyVideoConfigs( send_config->rtp.payload_name = "VP8"; encoder_config->codec_type = kVideoCodecVP8; std::vector streams = test::CreateVideoStreams( - test::CallTest::kDefaultWidth, test::CallTest::kDefaultHeight, - *encoder_config); + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight, *encoder_config); // For multi stream rampup until all streams are being sent. That means // enough bitrate to send all the target streams plus the min bitrate of // the last one. @@ -174,19 +175,22 @@ void RampUpTester::ModifyVideoConfigs( } } - send_config->rtp.nack.rtp_history_ms = test::CallTest::kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; send_config->rtp.ssrcs = video_ssrcs_; if (rtx_) { - send_config->rtp.rtx.payload_type = test::CallTest::kSendRtxPayloadType; + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; send_config->rtp.rtx.ssrcs = video_rtx_ssrcs_; } if (red_) { send_config->rtp.ulpfec.ulpfec_payload_type = - test::CallTest::kUlpfecPayloadType; - send_config->rtp.ulpfec.red_payload_type = test::CallTest::kRedPayloadType; + test::VideoTestConstants::kUlpfecPayloadType; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; if (rtx_) { send_config->rtp.ulpfec.red_rtx_payload_type = - test::CallTest::kRtxRedPayloadType; + test::VideoTestConstants::kRtxRedPayloadType; } } @@ -223,8 +227,9 @@ void RampUpTester::ModifyVideoConfigs( RTC_DCHECK_LE(num_flexfec_streams_, 1); if (num_flexfec_streams_ == 1) { - send_config->rtp.flexfec.payload_type = test::CallTest::kFlexfecPayloadType; - send_config->rtp.flexfec.ssrc = test::CallTest::kFlexfecSendSsrc; + send_config->rtp.flexfec.payload_type = + test::VideoTestConstants::kFlexfecPayloadType; + send_config->rtp.flexfec.ssrc = test::VideoTestConstants::kFlexfecSendSsrc; send_config->rtp.flexfec.protected_media_ssrcs = {video_ssrcs_[0]}; } } @@ -249,8 +254,10 @@ void RampUpTester::ModifyFlexfecConfigs( if (num_flexfec_streams_ == 0) return; RTC_DCHECK_EQ(1, num_flexfec_streams_); - (*receive_configs)[0].payload_type = test::CallTest::kFlexfecPayloadType; - (*receive_configs)[0].rtp.remote_ssrc = test::CallTest::kFlexfecSendSsrc; + (*receive_configs)[0].payload_type = + test::VideoTestConstants::kFlexfecPayloadType; + (*receive_configs)[0].rtp.remote_ssrc = + test::VideoTestConstants::kFlexfecSendSsrc; (*receive_configs)[0].protected_media_ssrcs = {video_ssrcs_[0]}; (*receive_configs)[0].rtp.local_ssrc = video_ssrcs_[0]; } diff --git a/third_party/libwebrtc/call/rtp_transport_controller_send.cc b/third_party/libwebrtc/call/rtp_transport_controller_send.cc index 2d871ceacd71d..5f3039065a33b 100644 --- a/third_party/libwebrtc/call/rtp_transport_controller_send.cc +++ b/third_party/libwebrtc/call/rtp_transport_controller_send.cc @@ -17,6 +17,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" #include "api/transport/goog_cc_factory.h" #include "api/transport/network_types.h" #include "api/units/data_rate.h" @@ -76,12 +77,12 @@ RtpTransportControllerSend::RtpTransportControllerSend( : clock_(clock), event_log_(config.event_log), task_queue_factory_(config.task_queue_factory), + task_queue_(TaskQueueBase::Current()), bitrate_configurator_(config.bitrate_config), pacer_started_(false), pacer_(clock, &packet_router_, *config.trials, - config.task_queue_factory, TimeDelta::Millis(5), 3, config.pacer_burst_interval), @@ -103,9 +104,6 @@ RtpTransportControllerSend::RtpTransportControllerSend( congestion_window_size_(DataSize::PlusInfinity()), is_congested_(false), retransmission_rate_limiter_(clock, kRetransmitWindowSizeMs), - task_queue_(*config.trials, - "rtp_send_controller", - config.task_queue_factory), field_trials_(*config.trials) { ParseFieldTrial({&relay_bandwidth_cap_}, config.trials->Lookup("WebRTC-Bwe-NetworkRouteConstraints")); @@ -121,15 +119,10 @@ RtpTransportControllerSend::RtpTransportControllerSend( } RtpTransportControllerSend::~RtpTransportControllerSend() { - RTC_DCHECK_RUN_ON(&main_thread_); + RTC_DCHECK_RUN_ON(&sequence_checker_); RTC_DCHECK(video_rtp_senders_.empty()); - if (task_queue_.IsCurrent()) { - // If these repeated tasks run on a task queue owned by - // `task_queue_`, they are stopped when the task queue is deleted. - // Otherwise, stop them here. - pacer_queue_update_task_.Stop(); - controller_task_.Stop(); - } + pacer_queue_update_task_.Stop(); + controller_task_.Stop(); } RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( @@ -143,7 +136,7 @@ RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( std::unique_ptr fec_controller, const RtpSenderFrameEncryptionConfig& frame_encryption_config, rtc::scoped_refptr frame_transformer) { - RTC_DCHECK_RUN_ON(&main_thread_); + RTC_DCHECK_RUN_ON(&sequence_checker_); video_rtp_senders_.push_back(std::make_unique( clock_, suspended_ssrcs, states, rtp_config, rtcp_report_interval_ms, send_transport, observers, @@ -158,7 +151,7 @@ RtpVideoSenderInterface* RtpTransportControllerSend::CreateRtpVideoSender( void RtpTransportControllerSend::DestroyRtpVideoSender( RtpVideoSenderInterface* rtp_video_sender) { - RTC_DCHECK_RUN_ON(&main_thread_); + RTC_DCHECK_RUN_ON(&sequence_checker_); std::vector>::iterator it = video_rtp_senders_.end(); for (it = video_rtp_senders_.begin(); it != video_rtp_senders_.end(); ++it) { @@ -196,10 +189,6 @@ absl::optional RtpTransportControllerSend::GetCongestedStateUpdate() return absl::nullopt; } -MaybeWorkerThread* RtpTransportControllerSend::GetWorkerQueue() { - return &task_queue_; -} - PacketRouter* RtpTransportControllerSend::packet_router() { return &packet_router_; } @@ -220,14 +209,14 @@ RtpPacketSender* RtpTransportControllerSend::packet_sender() { void RtpTransportControllerSend::SetAllocatedSendBitrateLimits( BitrateAllocationLimits limits) { - RTC_DCHECK_RUN_ON(&task_queue_); + RTC_DCHECK_RUN_ON(&sequence_checker_); streams_config_.min_total_allocated_bitrate = limits.min_allocatable_rate; streams_config_.max_padding_rate = limits.max_padding_rate; streams_config_.max_total_allocated_bitrate = limits.max_allocatable_rate; UpdateStreamsConfig(); } void RtpTransportControllerSend::SetPacingFactor(float pacing_factor) { - RTC_DCHECK_RUN_ON(&task_queue_); + RTC_DCHECK_RUN_ON(&sequence_checker_); streams_config_.pacing_factor = pacing_factor; UpdateStreamsConfig(); } @@ -241,13 +230,11 @@ RtpTransportControllerSend::GetStreamFeedbackProvider() { void RtpTransportControllerSend::RegisterTargetTransferRateObserver( TargetTransferRateObserver* observer) { - task_queue_.RunOrPost([this, observer] { - RTC_DCHECK_RUN_ON(&task_queue_); - RTC_DCHECK(observer_ == nullptr); - observer_ = observer; - observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate); - MaybeCreateControllers(); - }); + RTC_DCHECK_RUN_ON(&sequence_checker_); + RTC_DCHECK(observer_ == nullptr); + observer_ = observer; + observer_->OnStartRateUpdate(*initial_config_.constraints.starting_rate); + MaybeCreateControllers(); } bool RtpTransportControllerSend::IsRelevantRouteChange( @@ -270,8 +257,8 @@ bool RtpTransportControllerSend::IsRelevantRouteChange( void RtpTransportControllerSend::OnNetworkRouteChanged( absl::string_view transport_name, const rtc::NetworkRoute& network_route) { + RTC_DCHECK_RUN_ON(&sequence_checker_); // Check if the network route is connected. - if (!network_route.connected) { // TODO(honghaiz): Perhaps handle this in SignalChannelNetworkState and // consider merging these two methods. @@ -301,10 +288,7 @@ void RtpTransportControllerSend::OnNetworkRouteChanged( if (relay_constraint_update.has_value()) { UpdateBitrateConstraints(*relay_constraint_update); } - task_queue_.RunOrPost([this, network_route] { - RTC_DCHECK_RUN_ON(&task_queue_); - transport_overhead_bytes_per_packet_ = network_route.packet_overhead; - }); + transport_overhead_bytes_per_packet_ = network_route.packet_overhead; // No need to reset BWE if this is the first time the network connects. return; } @@ -330,51 +314,42 @@ void RtpTransportControllerSend::OnNetworkRouteChanged( NetworkRouteChange msg; msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds()); msg.constraints = ConvertConstraints(bitrate_config, clock_); - task_queue_.RunOrPost([this, msg, network_route] { - RTC_DCHECK_RUN_ON(&task_queue_); - transport_overhead_bytes_per_packet_ = network_route.packet_overhead; - if (reset_feedback_on_route_change_) { - transport_feedback_adapter_.SetNetworkRoute(network_route); - } - if (controller_) { - PostUpdates(controller_->OnNetworkRouteChange(msg)); - } else { - UpdateInitialConstraints(msg.constraints); - } - is_congested_ = false; - pacer_.SetCongested(false); - }); + transport_overhead_bytes_per_packet_ = network_route.packet_overhead; + if (reset_feedback_on_route_change_) { + transport_feedback_adapter_.SetNetworkRoute(network_route); + } + if (controller_) { + PostUpdates(controller_->OnNetworkRouteChange(msg)); + } else { + UpdateInitialConstraints(msg.constraints); + } + is_congested_ = false; + pacer_.SetCongested(false); } } void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) { - RTC_DCHECK_RUN_ON(&main_thread_); + RTC_DCHECK_RUN_ON(&sequence_checker_); RTC_LOG(LS_VERBOSE) << "SignalNetworkState " << (network_available ? "Up" : "Down"); NetworkAvailability msg; msg.at_time = Timestamp::Millis(clock_->TimeInMilliseconds()); msg.network_available = network_available; - task_queue_.RunOrPost([this, msg]() { - RTC_DCHECK_RUN_ON(&task_queue_); - if (network_available_ == msg.network_available) - return; - network_available_ = msg.network_available; - if (network_available_) { - pacer_.Resume(); - } else { - pacer_.Pause(); - } - is_congested_ = false; - pacer_.SetCongested(false); - - if (controller_) { - control_handler_->SetNetworkAvailability(network_available_); - PostUpdates(controller_->OnNetworkAvailability(msg)); - UpdateControlState(); - } else { - MaybeCreateControllers(); - } - }); + network_available_ = network_available; + if (network_available) { + pacer_.Resume(); + } else { + pacer_.Pause(); + } + is_congested_ = false; + pacer_.SetCongested(false); + if (controller_) { + control_handler_->SetNetworkAvailability(network_available); + PostUpdates(controller_->OnNetworkAvailability(msg)); + UpdateControlState(); + } else { + MaybeCreateControllers(); + } for (auto& rtp_sender : video_rtp_senders_) { rtp_sender->OnNetworkAvailability(network_available); } @@ -390,11 +365,10 @@ absl::optional RtpTransportControllerSend::GetFirstPacketTime() return pacer_.FirstSentPacketTime(); } void RtpTransportControllerSend::EnablePeriodicAlrProbing(bool enable) { - task_queue_.RunOrPost([this, enable]() { - RTC_DCHECK_RUN_ON(&task_queue_); - streams_config_.requests_alr_probing = enable; - UpdateStreamsConfig(); - }); + RTC_DCHECK_RUN_ON(&sequence_checker_); + + streams_config_.requests_alr_probing = enable; + UpdateStreamsConfig(); } void RtpTransportControllerSend::OnSentPacket( const rtc::SentPacket& sent_packet) { @@ -402,28 +376,22 @@ void RtpTransportControllerSend::OnSentPacket( // TODO(bugs.webrtc.org/137439): Clarify other thread contexts calling in, and // simplify task posting logic when the combined network/worker project // launches. - if (TaskQueueBase::Current() != task_queue_.TaskQueueForPost()) { - // We can't use SafeTask here if we are using an owned task queue, because - // the safety flag will be destroyed when RtpTransportControllerSend is - // destroyed on the worker thread. But we must use SafeTask if we are using - // the worker thread, since the worker thread outlives - // RtpTransportControllerSend. - task_queue_.TaskQueueForPost()->PostTask( - task_queue_.MaybeSafeTask(safety_.flag(), [this, sent_packet]() { - RTC_DCHECK_RUN_ON(&task_queue_); - ProcessSentPacket(sent_packet, /*posted_to_worker=*/true); - })); + if (TaskQueueBase::Current() != task_queue_) { + task_queue_->PostTask(SafeTask(safety_.flag(), [this, sent_packet]() { + RTC_DCHECK_RUN_ON(&sequence_checker_); + ProcessSentPacket(sent_packet, /*posted_to_worker=*/true); + })); return; } - RTC_DCHECK_RUN_ON(&task_queue_); + RTC_DCHECK_RUN_ON(&sequence_checker_); ProcessSentPacket(sent_packet, /*posted_to_worker=*/false); } -// RTC_RUN_ON(task_queue_) void RtpTransportControllerSend::ProcessSentPacket( const rtc::SentPacket& sent_packet, bool posted_to_worker) { + RTC_DCHECK_RUN_ON(&sequence_checker_); absl::optional packet_msg = transport_feedback_adapter_.ProcessSentPacket(sent_packet); if (!packet_msg) @@ -446,18 +414,19 @@ void RtpTransportControllerSend::ProcessSentPacket( // PacketRouter::SendPacket, we need to break the chain here and PostTask to // get out of the lock. In testing, having updates to process happens pretty // rarely so we do not usually get here. - task_queue_.TaskQueueForPost()->PostTask(task_queue_.MaybeSafeTask( - safety_.flag(), - [this, control_update = std::move(control_update)]() mutable { - RTC_DCHECK_RUN_ON(&task_queue_); - ProcessSentPacketUpdates(std::move(control_update)); - })); + task_queue_->PostTask( + SafeTask(safety_.flag(), + [this, control_update = std::move(control_update)]() mutable { + RTC_DCHECK_RUN_ON(&sequence_checker_); + ProcessSentPacketUpdates(std::move(control_update)); + })); } } // RTC_RUN_ON(task_queue_) void RtpTransportControllerSend::ProcessSentPacketUpdates( NetworkControlUpdate updates) { + RTC_DCHECK_RUN_ON(&sequence_checker_); // Only update outstanding data if: // 1. Packet feedback is used. // 2. The packet has not yet received an acknowledgement. @@ -470,28 +439,25 @@ void RtpTransportControllerSend::ProcessSentPacketUpdates( void RtpTransportControllerSend::OnReceivedPacket( const ReceivedPacket& packet_msg) { - task_queue_.RunOrPost([this, packet_msg]() { - RTC_DCHECK_RUN_ON(&task_queue_); - if (controller_) - PostUpdates(controller_->OnReceivedPacket(packet_msg)); - }); + RTC_DCHECK_RUN_ON(&sequence_checker_); + if (controller_) + PostUpdates(controller_->OnReceivedPacket(packet_msg)); } void RtpTransportControllerSend::UpdateBitrateConstraints( const BitrateConstraints& updated) { + RTC_DCHECK_RUN_ON(&sequence_checker_); TargetRateConstraints msg = ConvertConstraints(updated, clock_); - task_queue_.RunOrPost([this, msg]() { - RTC_DCHECK_RUN_ON(&task_queue_); - if (controller_) { - PostUpdates(controller_->OnTargetRateConstraints(msg)); - } else { - UpdateInitialConstraints(msg); - } - }); + if (controller_) { + PostUpdates(controller_->OnTargetRateConstraints(msg)); + } else { + UpdateInitialConstraints(msg); + } } void RtpTransportControllerSend::SetSdpBitrateParameters( const BitrateConstraints& constraints) { + RTC_DCHECK_RUN_ON(&sequence_checker_); absl::optional updated = bitrate_configurator_.UpdateWithSdpParameters(constraints); if (updated.has_value()) { @@ -505,6 +471,7 @@ void RtpTransportControllerSend::SetSdpBitrateParameters( void RtpTransportControllerSend::SetClientBitratePreferences( const BitrateSettings& preferences) { + RTC_DCHECK_RUN_ON(&sequence_checker_); absl::optional updated = bitrate_configurator_.UpdateWithClientPreferences(preferences); if (updated.has_value()) { @@ -524,7 +491,7 @@ RtpTransportControllerSend::ApplyOrLiftRelayCap(bool is_relayed) { void RtpTransportControllerSend::OnTransportOverheadChanged( size_t transport_overhead_bytes_per_packet) { - RTC_DCHECK_RUN_ON(&main_thread_); + RTC_DCHECK_RUN_ON(&sequence_checker_); if (transport_overhead_bytes_per_packet >= kMaxOverheadBytes) { RTC_LOG(LS_ERROR) << "Transport overhead exceeds " << kMaxOverheadBytes; return; @@ -551,6 +518,7 @@ void RtpTransportControllerSend::IncludeOverheadInPacedSender() { } void RtpTransportControllerSend::EnsureStarted() { + RTC_DCHECK_RUN_ON(&sequence_checker_); if (!pacer_started_) { pacer_started_ = true; pacer_.EnsureStarted(); @@ -558,75 +526,64 @@ void RtpTransportControllerSend::EnsureStarted() { } void RtpTransportControllerSend::OnReceivedEstimatedBitrate(uint32_t bitrate) { + RTC_DCHECK_RUN_ON(&sequence_checker_); RemoteBitrateReport msg; msg.receive_time = Timestamp::Millis(clock_->TimeInMilliseconds()); msg.bandwidth = DataRate::BitsPerSec(bitrate); - task_queue_.RunOrPost([this, msg]() { - RTC_DCHECK_RUN_ON(&task_queue_); - if (controller_) - PostUpdates(controller_->OnRemoteBitrateReport(msg)); - }); + if (controller_) + PostUpdates(controller_->OnRemoteBitrateReport(msg)); } void RtpTransportControllerSend::OnReceivedRtcpReceiverReport( const ReportBlockList& report_blocks, int64_t rtt_ms, int64_t now_ms) { - task_queue_.RunOrPost([this, report_blocks, now_ms, rtt_ms]() { - RTC_DCHECK_RUN_ON(&task_queue_); - OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms); - RoundTripTimeUpdate report; - report.receive_time = Timestamp::Millis(now_ms); - report.round_trip_time = TimeDelta::Millis(rtt_ms); - report.smoothed = false; - if (controller_ && !report.round_trip_time.IsZero()) - PostUpdates(controller_->OnRoundTripTimeUpdate(report)); - }); + RTC_DCHECK_RUN_ON(&sequence_checker_); + OnReceivedRtcpReceiverReportBlocks(report_blocks, now_ms); + RoundTripTimeUpdate report; + report.receive_time = Timestamp::Millis(now_ms); + report.round_trip_time = TimeDelta::Millis(rtt_ms); + report.smoothed = false; + if (controller_ && !report.round_trip_time.IsZero()) + PostUpdates(controller_->OnRoundTripTimeUpdate(report)); } void RtpTransportControllerSend::OnAddPacket( const RtpPacketSendInfo& packet_info) { + RTC_DCHECK_RUN_ON(&sequence_checker_); Timestamp creation_time = Timestamp::Millis(clock_->TimeInMilliseconds()); - - task_queue_.RunOrPost([this, packet_info, creation_time]() { - RTC_DCHECK_RUN_ON(&task_queue_); - feedback_demuxer_.AddPacket(packet_info); - transport_feedback_adapter_.AddPacket( - packet_info, transport_overhead_bytes_per_packet_, creation_time); - }); + feedback_demuxer_.AddPacket(packet_info); + transport_feedback_adapter_.AddPacket( + packet_info, transport_overhead_bytes_per_packet_, creation_time); } void RtpTransportControllerSend::OnTransportFeedback( const rtcp::TransportFeedback& feedback) { + RTC_DCHECK_RUN_ON(&sequence_checker_); auto feedback_time = Timestamp::Millis(clock_->TimeInMilliseconds()); - task_queue_.RunOrPost([this, feedback, feedback_time]() { - RTC_DCHECK_RUN_ON(&task_queue_); - feedback_demuxer_.OnTransportFeedback(feedback); - absl::optional feedback_msg = - transport_feedback_adapter_.ProcessTransportFeedback(feedback, - feedback_time); - if (feedback_msg) { - if (controller_) - PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg)); - - // Only update outstanding data if any packet is first time acked. - UpdateCongestedState(); - } - }); + feedback_demuxer_.OnTransportFeedback(feedback); + absl::optional feedback_msg = + transport_feedback_adapter_.ProcessTransportFeedback(feedback, + feedback_time); + if (feedback_msg) { + if (controller_) + PostUpdates(controller_->OnTransportPacketsFeedback(*feedback_msg)); + + // Only update outstanding data if any packet is first time acked. + UpdateCongestedState(); + } } void RtpTransportControllerSend::OnRemoteNetworkEstimate( NetworkStateEstimate estimate) { + RTC_DCHECK_RUN_ON(&sequence_checker_); if (event_log_) { event_log_->Log(std::make_unique( estimate.link_capacity_lower, estimate.link_capacity_upper)); } estimate.update_time = Timestamp::Millis(clock_->TimeInMilliseconds()); - task_queue_.RunOrPost([this, estimate] { - RTC_DCHECK_RUN_ON(&task_queue_); - if (controller_) - PostUpdates(controller_->OnNetworkStateEstimate(estimate)); - }); + if (controller_) + PostUpdates(controller_->OnNetworkStateEstimate(estimate)); } void RtpTransportControllerSend::MaybeCreateControllers() { @@ -664,12 +621,11 @@ void RtpTransportControllerSend::UpdateInitialConstraints( } void RtpTransportControllerSend::StartProcessPeriodicTasks() { - RTC_DCHECK_RUN_ON(&task_queue_); + RTC_DCHECK_RUN_ON(&sequence_checker_); if (!pacer_queue_update_task_.Running()) { pacer_queue_update_task_ = RepeatingTaskHandle::DelayedStart( - task_queue_.TaskQueueForDelayedTasks(), kPacerQueueUpdateInterval, - [this]() { - RTC_DCHECK_RUN_ON(&task_queue_); + task_queue_, kPacerQueueUpdateInterval, [this]() { + RTC_DCHECK_RUN_ON(&sequence_checker_); TimeDelta expected_queue_time = pacer_.ExpectedQueueTime(); control_handler_->SetPacerQueue(expected_queue_time); UpdateControlState(); @@ -679,8 +635,8 @@ void RtpTransportControllerSend::StartProcessPeriodicTasks() { controller_task_.Stop(); if (process_interval_.IsFinite()) { controller_task_ = RepeatingTaskHandle::DelayedStart( - task_queue_.TaskQueueForDelayedTasks(), process_interval_, [this]() { - RTC_DCHECK_RUN_ON(&task_queue_); + task_queue_, process_interval_, [this]() { + RTC_DCHECK_RUN_ON(&sequence_checker_); UpdateControllerWithTimeInterval(); return process_interval_; }); @@ -723,6 +679,7 @@ void RtpTransportControllerSend::PostUpdates(NetworkControlUpdate update) { void RtpTransportControllerSend::OnReceivedRtcpReceiverReportBlocks( const ReportBlockList& report_blocks, int64_t now_ms) { + RTC_DCHECK_RUN_ON(&sequence_checker_); if (report_blocks.empty()) return; diff --git a/third_party/libwebrtc/call/rtp_transport_controller_send.h b/third_party/libwebrtc/call/rtp_transport_controller_send.h index eaac55f8293a0..02a7f524a4941 100644 --- a/third_party/libwebrtc/call/rtp_transport_controller_send.h +++ b/third_party/libwebrtc/call/rtp_transport_controller_send.h @@ -34,7 +34,6 @@ #include "modules/pacing/packet_router.h" #include "modules/pacing/rtp_packet_pacer.h" #include "modules/pacing/task_queue_paced_sender.h" -#include "modules/utility/maybe_worker_thread.h" #include "rtc_base/network_route.h" #include "rtc_base/race_checker.h" #include "rtc_base/task_queue.h" @@ -75,7 +74,6 @@ class RtpTransportControllerSend final RtpVideoSenderInterface* rtp_video_sender) override; // Implements RtpTransportControllerSendInterface - MaybeWorkerThread* GetWorkerQueue() override; PacketRouter* packet_router() override; NetworkStateEstimateObserver* network_state_estimate_observer() override; @@ -123,85 +121,88 @@ class RtpTransportControllerSend final void OnRemoteNetworkEstimate(NetworkStateEstimate estimate) override; private: - void MaybeCreateControllers() RTC_RUN_ON(task_queue_); + void MaybeCreateControllers() RTC_RUN_ON(sequence_checker_); void UpdateInitialConstraints(TargetRateConstraints new_contraints) - RTC_RUN_ON(task_queue_); + RTC_RUN_ON(sequence_checker_); - void StartProcessPeriodicTasks() RTC_RUN_ON(task_queue_); - void UpdateControllerWithTimeInterval() RTC_RUN_ON(task_queue_); + void StartProcessPeriodicTasks() RTC_RUN_ON(sequence_checker_); + void UpdateControllerWithTimeInterval() RTC_RUN_ON(sequence_checker_); absl::optional ApplyOrLiftRelayCap(bool is_relayed); bool IsRelevantRouteChange(const rtc::NetworkRoute& old_route, const rtc::NetworkRoute& new_route) const; void UpdateBitrateConstraints(const BitrateConstraints& updated); - void UpdateStreamsConfig() RTC_RUN_ON(task_queue_); + void UpdateStreamsConfig() RTC_RUN_ON(sequence_checker_); void OnReceivedRtcpReceiverReportBlocks(const ReportBlockList& report_blocks, int64_t now_ms) - RTC_RUN_ON(task_queue_); - void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(task_queue_); - void UpdateControlState() RTC_RUN_ON(task_queue_); - void UpdateCongestedState() RTC_RUN_ON(task_queue_); - absl::optional GetCongestedStateUpdate() const RTC_RUN_ON(task_queue_); + RTC_RUN_ON(sequence_checker_); + void PostUpdates(NetworkControlUpdate update) RTC_RUN_ON(sequence_checker_); + void UpdateControlState() RTC_RUN_ON(sequence_checker_); + void UpdateCongestedState() RTC_RUN_ON(sequence_checker_); + absl::optional GetCongestedStateUpdate() const + RTC_RUN_ON(sequence_checker_); void ProcessSentPacket(const rtc::SentPacket& sent_packet, - bool posted_to_worker) RTC_RUN_ON(task_queue_); + bool posted_to_worker) RTC_RUN_ON(sequence_checker_); void ProcessSentPacketUpdates(NetworkControlUpdate updates) - RTC_RUN_ON(task_queue_); + RTC_RUN_ON(sequence_checker_); Clock* const clock_; RtcEventLog* const event_log_; TaskQueueFactory* const task_queue_factory_; - SequenceChecker main_thread_; + SequenceChecker sequence_checker_; + TaskQueueBase* task_queue_; PacketRouter packet_router_; std::vector> video_rtp_senders_ - RTC_GUARDED_BY(&main_thread_); + RTC_GUARDED_BY(&sequence_checker_); RtpBitrateConfigurator bitrate_configurator_; - std::map network_routes_; - bool pacer_started_; + std::map network_routes_ + RTC_GUARDED_BY(sequence_checker_); + bool pacer_started_ RTC_GUARDED_BY(sequence_checker_); TaskQueuePacedSender pacer_; - TargetTransferRateObserver* observer_ RTC_GUARDED_BY(task_queue_); + TargetTransferRateObserver* observer_ RTC_GUARDED_BY(sequence_checker_); TransportFeedbackDemuxer feedback_demuxer_; TransportFeedbackAdapter transport_feedback_adapter_ - RTC_GUARDED_BY(task_queue_); + RTC_GUARDED_BY(sequence_checker_); NetworkControllerFactoryInterface* const controller_factory_override_ - RTC_PT_GUARDED_BY(task_queue_); + RTC_PT_GUARDED_BY(sequence_checker_); const std::unique_ptr - controller_factory_fallback_ RTC_PT_GUARDED_BY(task_queue_); + controller_factory_fallback_ RTC_PT_GUARDED_BY(sequence_checker_); std::unique_ptr control_handler_ - RTC_GUARDED_BY(task_queue_) RTC_PT_GUARDED_BY(task_queue_); + RTC_GUARDED_BY(sequence_checker_) RTC_PT_GUARDED_BY(sequence_checker_); std::unique_ptr controller_ - RTC_GUARDED_BY(task_queue_) RTC_PT_GUARDED_BY(task_queue_); + RTC_GUARDED_BY(sequence_checker_) RTC_PT_GUARDED_BY(sequence_checker_); - TimeDelta process_interval_ RTC_GUARDED_BY(task_queue_); + TimeDelta process_interval_ RTC_GUARDED_BY(sequence_checker_); std::map last_report_blocks_ - RTC_GUARDED_BY(task_queue_); - Timestamp last_report_block_time_ RTC_GUARDED_BY(task_queue_); + RTC_GUARDED_BY(sequence_checker_); + Timestamp last_report_block_time_ RTC_GUARDED_BY(sequence_checker_); - NetworkControllerConfig initial_config_ RTC_GUARDED_BY(task_queue_); - StreamsConfig streams_config_ RTC_GUARDED_BY(task_queue_); + NetworkControllerConfig initial_config_ RTC_GUARDED_BY(sequence_checker_); + StreamsConfig streams_config_ RTC_GUARDED_BY(sequence_checker_); const bool reset_feedback_on_route_change_; const bool add_pacing_to_cwin_; FieldTrialParameter relay_bandwidth_cap_; - size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(task_queue_); - bool network_available_ RTC_GUARDED_BY(task_queue_); - RepeatingTaskHandle pacer_queue_update_task_ RTC_GUARDED_BY(task_queue_); - RepeatingTaskHandle controller_task_ RTC_GUARDED_BY(task_queue_); + size_t transport_overhead_bytes_per_packet_ RTC_GUARDED_BY(sequence_checker_); + bool network_available_ RTC_GUARDED_BY(sequence_checker_); + RepeatingTaskHandle pacer_queue_update_task_ + RTC_GUARDED_BY(sequence_checker_); + RepeatingTaskHandle controller_task_ RTC_GUARDED_BY(sequence_checker_); - DataSize congestion_window_size_ RTC_GUARDED_BY(task_queue_); - bool is_congested_ RTC_GUARDED_BY(task_queue_); + DataSize congestion_window_size_ RTC_GUARDED_BY(sequence_checker_); + bool is_congested_ RTC_GUARDED_BY(sequence_checker_); // Protected by internal locks. RateLimiter retransmission_rate_limiter_; ScopedTaskSafety safety_; - MaybeWorkerThread task_queue_; const FieldTrialsView& field_trials_; }; diff --git a/third_party/libwebrtc/call/rtp_transport_controller_send_interface.h b/third_party/libwebrtc/call/rtp_transport_controller_send_interface.h index 44df5aa7361cb..6ac2d84d033f4 100644 --- a/third_party/libwebrtc/call/rtp_transport_controller_send_interface.h +++ b/third_party/libwebrtc/call/rtp_transport_controller_send_interface.h @@ -42,7 +42,6 @@ class TaskQueue; namespace webrtc { class FrameEncryptorInterface; -class MaybeWorkerThread; class TargetTransferRateObserver; class Transport; class PacketRouter; @@ -94,9 +93,6 @@ struct RtpSenderFrameEncryptionConfig { class RtpTransportControllerSendInterface { public: virtual ~RtpTransportControllerSendInterface() {} - // TODO(webrtc:14502): Remove MaybeWorkerThread when experiment has been - // evaluated. - virtual MaybeWorkerThread* GetWorkerQueue() = 0; virtual PacketRouter* packet_router() = 0; virtual RtpVideoSenderInterface* CreateRtpVideoSender( diff --git a/third_party/libwebrtc/call/rtp_video_sender.cc b/third_party/libwebrtc/call/rtp_video_sender.cc index 38f48de41a876..708aa81f4e240 100644 --- a/third_party/libwebrtc/call/rtp_video_sender.cc +++ b/third_party/libwebrtc/call/rtp_video_sender.cc @@ -27,7 +27,6 @@ #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" #include "modules/rtp_rtcp/source/rtp_sender.h" -#include "modules/utility/maybe_worker_thread.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" diff --git a/third_party/libwebrtc/call/rtp_video_sender_unittest.cc b/third_party/libwebrtc/call/rtp_video_sender_unittest.cc index 3181cfb0a4328..f7407e7d65bf4 100644 --- a/third_party/libwebrtc/call/rtp_video_sender_unittest.cc +++ b/third_party/libwebrtc/call/rtp_video_sender_unittest.cc @@ -193,24 +193,10 @@ class RtpVideoSenderTestFixture { MockTransport& transport() { return transport_; } void AdvanceTime(TimeDelta delta) { time_controller_.AdvanceTime(delta); } - void Stop() { - RunOnTransportQueue([&]() { router_->Stop(); }); - } + void Stop() { router_->Stop(); } void SetActiveModules(const std::vector& active_modules) { - RunOnTransportQueue([&]() { router_->SetActiveModules(active_modules); }); - } - - // Several RtpVideoSender methods expect to be called on the task queue as - // owned by the send transport. While the SequenceChecker may pick up the - // default thread as the transport queue, explicit checks for the transport - // queue (not just using a SequenceChecker) aren't possible unless such a - // queue is actually active. So RunOnTransportQueue is a convenience function - // that allow for running a `task` on the transport queue, similar to - // SendTask(). - void RunOnTransportQueue(absl::AnyInvocable task) { - transport_controller_.GetWorkerQueue()->RunOrPost(std::move(task)); - AdvanceTime(TimeDelta::Zero()); + router_->SetActiveModules(active_modules); } private: diff --git a/third_party/libwebrtc/call/test/mock_rtp_transport_controller_send.h b/third_party/libwebrtc/call/test/mock_rtp_transport_controller_send.h index 6e78534de25e1..0c522dfff468a 100644 --- a/third_party/libwebrtc/call/test/mock_rtp_transport_controller_send.h +++ b/third_party/libwebrtc/call/test/mock_rtp_transport_controller_send.h @@ -50,7 +50,6 @@ class MockRtpTransportControllerSend DestroyRtpVideoSender, (RtpVideoSenderInterface*), (override)); - MOCK_METHOD(MaybeWorkerThread*, GetWorkerQueue, (), (override)); MOCK_METHOD(PacketRouter*, packet_router, (), (override)); MOCK_METHOD(NetworkStateEstimateObserver*, network_state_estimate_observer, diff --git a/third_party/libwebrtc/call/version.cc b/third_party/libwebrtc/call/version.cc index 5322b266ee5b5..33d2ad712393f 100644 --- a/third_party/libwebrtc/call/version.cc +++ b/third_party/libwebrtc/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2023-03-22T04:02:52"; +const char* const kSourceTimestamp = "WebRTC source stamp 2023-04-24T04:05:22"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even diff --git a/third_party/libwebrtc/examples/BUILD.gn b/third_party/libwebrtc/examples/BUILD.gn index 18cb6ecc67958..9fa5d6f6187cf 100644 --- a/third_party/libwebrtc/examples/BUILD.gn +++ b/third_party/libwebrtc/examples/BUILD.gn @@ -28,7 +28,9 @@ group("examples") { deps += [ ":AppRTCMobile", ":AppRTCMobile_test_apk", - ":libwebrtc_unity", + + #TODO(https://bugs.webrtc.org/15095) - Fix or remove this target. + #":libwebrtc_unity", "androidvoip", ] @@ -221,7 +223,7 @@ if (is_android) { "../sdk/android:peerconnection_java", "../sdk/android:video_api_java", "../sdk/android:video_java", - "//third_party/android_support_test_runner:runner_java", + "//third_party/androidx:androidx_test_monitor_java", "//third_party/androidx:androidx_test_runner_java", "//third_party/junit", ] @@ -754,8 +756,16 @@ if (is_linux || is_chromeos || is_win) { "../api/audio_codecs:builtin_audio_encoder_factory", "../api/video:video_frame", "../api/video:video_rtp_headers", - "../api/video_codecs:builtin_video_decoder_factory", - "../api/video_codecs:builtin_video_encoder_factory", + "../api/video_codecs:video_decoder_factory_template", + "../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../media:rtc_audio_video", "../modules/audio_device", "../modules/audio_processing", @@ -893,21 +903,22 @@ if (is_android) { ] } - dist_jar("libwebrtc_unity") { - _target_dir_name = get_label_info(":$target_name", "dir") - output = "${root_out_dir}/lib.java${_target_dir_name}/${target_name}.jar" - direct_deps_only = false - use_interface_jars = false - use_unprocessed_jars = false - requires_android = true - deps = [ - ":webrtc_unity_java", - "../rtc_base:base_java", - "../sdk/android:libjingle_peerconnection_java", - "../sdk/android:libjingle_peerconnection_metrics_default_java", - "//third_party/androidx:androidx_annotation_annotation_java", - ] - } + # TODO(https://bugs.webrtc.org/15095) - Fix or remove this target. + #dist_jar("libwebrtc_unity") { + # _target_dir_name = get_label_info(":$target_name", "dir") + # output = "${root_out_dir}/lib.java${_target_dir_name}/${target_name}.jar" + # direct_deps_only = false + # use_interface_jars = false + # use_unprocessed_jars = false + # requires_android = true + # deps = [ + # ":webrtc_unity_java", + # "../rtc_base:base_java", + # "../sdk/android:libjingle_peerconnection_java", + # "../sdk/android:libjingle_peerconnection_metrics_default_java", + # "//third_party/androidx:androidx_annotation_annotation_java", + # ] + #} robolectric_binary("android_examples_junit_tests") { sources = [ diff --git a/third_party/libwebrtc/examples/aarproject/app/build.gradle b/third_party/libwebrtc/examples/aarproject/app/build.gradle index c44d1d1fd1f76..70669c3b633b5 100644 --- a/third_party/libwebrtc/examples/aarproject/app/build.gradle +++ b/third_party/libwebrtc/examples/aarproject/app/build.gradle @@ -48,6 +48,6 @@ dependencies { implementation fileTree(dir: '../../androidapp/third_party/autobanh/lib', include: ['autobanh.jar']) implementation 'androidx.annotation:annotation:1.2.0' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' + androidTestImplementation 'com.androidx.test:runner:1.0.1' + androidTestImplementation 'com.androidx.test.espresso:espresso-core:3.0.1' } diff --git a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java index 3060bd7a56fe0..d7c190518cee1 100644 --- a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java +++ b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java @@ -33,12 +33,12 @@ import java.util.ArrayList; import java.util.List; import org.appspot.apprtc.AppRTCBluetoothManager.State; -import org.chromium.testing.local.LocalRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; +import org.robolectric.RobolectricTestRunner; /** * Verifies basic behavior of the AppRTCBluetoothManager class. @@ -46,7 +46,7 @@ * but a mocked version is used instead. Hence, the parts "driven" by the AppRTC * audio manager are not included in this test. */ -@RunWith(LocalRobolectricTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) public class BluetoothManagerTest { private static final String TAG = "BluetoothManagerTest"; diff --git a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/DirectRTCClientTest.java b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/DirectRTCClientTest.java index 2da8164ec73e8..1ee0e41390046 100644 --- a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/DirectRTCClientTest.java +++ b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/DirectRTCClientTest.java @@ -20,12 +20,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import org.chromium.testing.local.LocalRobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; +import org.robolectric.RobolectricTestRunner; import org.webrtc.IceCandidate; import org.webrtc.SessionDescription; @@ -33,7 +33,7 @@ * Test for DirectRTCClient. Test is very simple and only tests the overall sanity of the class * behaviour. */ -@RunWith(LocalRobolectricTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) public class DirectRTCClientTest { private static final String ROOM_URL = ""; diff --git a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/TCPChannelClientTest.java b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/TCPChannelClientTest.java index b301d6317c74e..ce550b35e4a4f 100644 --- a/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/TCPChannelClientTest.java +++ b/third_party/libwebrtc/examples/androidjunit/src/org/appspot/apprtc/TCPChannelClientTest.java @@ -15,7 +15,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; -import org.chromium.testing.local.LocalRobolectricTestRunner; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -24,12 +23,13 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowLog; +import org.robolectric.RobolectricTestRunner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -@RunWith(LocalRobolectricTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE) public class TCPChannelClientTest { private static final int PORT = 8888; diff --git a/third_party/libwebrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/third_party/libwebrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java index 051d7379bdc16..9c3c779600dc8 100644 --- a/third_party/libwebrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java +++ b/third_party/libwebrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java @@ -14,10 +14,10 @@ import static org.junit.Assert.fail; import android.os.Build; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; import android.util.Log; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; diff --git a/third_party/libwebrtc/examples/peerconnection/client/conductor.cc b/third_party/libwebrtc/examples/peerconnection/client/conductor.cc index 052d417d7f82e..f94a981a75399 100644 --- a/third_party/libwebrtc/examples/peerconnection/client/conductor.cc +++ b/third_party/libwebrtc/examples/peerconnection/client/conductor.cc @@ -27,10 +27,18 @@ #include "api/audio_options.h" #include "api/create_peerconnection_factory.h" #include "api/rtp_sender_interface.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" #include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "examples/peerconnection/client/defaults.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -137,9 +145,17 @@ bool Conductor::InitializePeerConnection() { signaling_thread_.get(), nullptr /* default_adm */, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); if (!peer_connection_factory_) { main_wnd_->MessageBox("Error", "Failed to initialize PeerConnectionFactory", diff --git a/third_party/libwebrtc/infra/config/commit-queue.cfg b/third_party/libwebrtc/infra/config/commit-queue.cfg index 0ffe43eae9be2..b9de582da1591 100644 --- a/third_party/libwebrtc/infra/config/commit-queue.cfg +++ b/third_party/libwebrtc/infra/config/commit-queue.cfg @@ -179,6 +179,12 @@ config_groups { builders { name: "webrtc/try/win_compile_x86_clang_dbg" } + builders { + name: "webrtc/try/win_x64_clang_dbg" + } + builders { + name: "webrtc/try/win_x64_clang_rel" + } builders { name: "webrtc/try/win_x86_clang_rel" } @@ -338,6 +344,12 @@ config_groups { builders { name: "webrtc/try/win_compile_x86_clang_dbg" } + builders { + name: "webrtc/try/win_x64_clang_dbg" + } + builders { + name: "webrtc/try/win_x64_clang_rel" + } builders { name: "webrtc/try/win_x86_clang_rel" } diff --git a/third_party/libwebrtc/infra/config/config.star b/third_party/libwebrtc/infra/config/config.star index d10b781c9f2ae..93c570341a32e 100755 --- a/third_party/libwebrtc/infra/config/config.star +++ b/third_party/libwebrtc/infra/config/config.star @@ -602,8 +602,9 @@ def perf_builder(name, perf_cat, **kwargs): properties = make_reclient_properties("rbe-webrtc-trusted") properties["builder_group"] = "client.webrtc.perf" dimensions = {"pool": "luci.webrtc.perf", "os": "Linux", "cores": "2"} - if "Android" in name: + if "Android" in name or "Fuchsia" in name: # Android perf testers require more performant bots to finish under 3 hours. + # Fuchsia perf testers encountered "no space left on device" error on multiple runs. dimensions["cores"] = "8" return webrtc_builder( name = name, @@ -788,10 +789,10 @@ win_try_job("win_compile_x86_clang_rel", cq = None) win_builder("Win64 Builder (Clang)", ci_cat = None, perf_cat = "Win|x64|Builder|") perf_builder("Perf Win 10", "Win|x64|Tester|10", triggered_by = ["Win64 Builder (Clang)"]) win_builder("Win64 Debug (Clang)", "Win Clang|x64|dbg") -win_try_job("win_x64_clang_dbg", cq = None) +win_try_job("win_x64_clang_dbg") win_try_job("win_compile_x64_clang_dbg") win_builder("Win64 Release (Clang)", "Win Clang|x64|rel") -win_try_job("win_x64_clang_rel", cq = None) +win_try_job("win_x64_clang_rel") win_try_job("win_compile_x64_clang_rel") win_builder("Win64 ASan", "Win Clang|x64|asan") win_try_job("win_asan") diff --git a/third_party/libwebrtc/infra/config/cr-buildbucket.cfg b/third_party/libwebrtc/infra/config/cr-buildbucket.cfg index 85b47c076879f..f4b37ebed1168 100644 --- a/third_party/libwebrtc/infra/config/cr-buildbucket.cfg +++ b/third_party/libwebrtc/infra/config/cr-buildbucket.cfg @@ -2445,7 +2445,7 @@ buckets { name: "Perf Fuchsia" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" - dimensions: "cores:2" + dimensions: "cores:8" dimensions: "os:Linux" dimensions: "pool:luci.webrtc.perf" exe { diff --git a/third_party/libwebrtc/infra/config/project.cfg b/third_party/libwebrtc/infra/config/project.cfg index f85deed489915..640686739d965 100644 --- a/third_party/libwebrtc/infra/config/project.cfg +++ b/third_party/libwebrtc/infra/config/project.cfg @@ -7,7 +7,7 @@ name: "webrtc" access: "group:all" lucicfg { - version: "1.38.1" + version: "1.39.4" package_dir: "." config_dir: "." entry_point: "config.star" diff --git a/third_party/libwebrtc/infra/specs/client.webrtc.json b/third_party/libwebrtc/infra/specs/client.webrtc.json index 7ca310eb879fa..833889957ddb6 100644 --- a/third_party/libwebrtc/infra/specs/client.webrtc.json +++ b/third_party/libwebrtc/infra/specs/client.webrtc.json @@ -5,7 +5,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -28,7 +27,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -51,7 +49,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -74,7 +71,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -97,7 +93,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -120,7 +115,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -143,7 +137,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -167,7 +160,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -191,7 +183,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -214,7 +205,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -238,7 +228,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -261,7 +250,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -284,7 +272,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -307,7 +294,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -331,7 +317,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -354,7 +339,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -378,7 +362,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -401,7 +384,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -424,7 +406,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -447,7 +428,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -471,7 +451,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -494,7 +473,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -543,7 +521,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -566,7 +543,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -589,7 +565,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -612,7 +587,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -635,7 +609,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -658,7 +631,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -681,7 +653,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -705,7 +676,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -729,7 +699,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -752,7 +721,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -776,7 +744,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -799,7 +766,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -822,7 +788,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -845,7 +810,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -869,7 +833,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -892,7 +855,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -916,7 +878,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -939,7 +900,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -962,7 +922,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -985,7 +944,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1009,7 +967,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1032,7 +989,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1081,7 +1037,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1112,7 +1067,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1135,7 +1089,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1158,7 +1111,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1181,7 +1133,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1204,7 +1155,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1227,7 +1177,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1250,7 +1199,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1274,7 +1222,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1298,7 +1245,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1321,7 +1267,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1345,7 +1290,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1368,7 +1312,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1391,7 +1334,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1414,7 +1356,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1438,7 +1379,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1461,7 +1401,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1485,7 +1424,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1508,7 +1446,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1531,7 +1468,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1554,7 +1490,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1578,7 +1513,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1601,7 +1535,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1650,7 +1583,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1673,7 +1605,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1696,7 +1627,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1719,7 +1649,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1742,7 +1671,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1765,7 +1693,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1788,7 +1715,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1812,7 +1738,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1836,7 +1761,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1859,7 +1783,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1883,7 +1806,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1906,7 +1828,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1929,7 +1850,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1952,7 +1872,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1976,7 +1895,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1999,7 +1917,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2023,7 +1940,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2046,7 +1962,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2069,7 +1984,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2092,7 +2006,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2116,7 +2029,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2139,7 +2051,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2198,7 +2109,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -2226,7 +2136,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -2254,7 +2163,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -2282,7 +2190,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -2311,7 +2218,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -2339,7 +2245,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -2367,7 +2272,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -2395,7 +2299,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -2424,7 +2327,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -2452,7 +2354,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -2481,7 +2382,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -2509,7 +2409,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -2535,7 +2434,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -2561,7 +2459,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -2582,7 +2479,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -2603,7 +2499,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -2624,7 +2519,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -2648,7 +2542,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -2669,7 +2562,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -2691,7 +2583,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -2713,7 +2604,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -2734,7 +2624,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -2756,7 +2645,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -2777,7 +2665,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -2798,7 +2685,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -2819,7 +2705,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -2841,7 +2726,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -2862,7 +2746,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -2883,7 +2766,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -2905,7 +2787,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -2926,7 +2807,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -2947,7 +2827,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -2968,7 +2847,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -2990,7 +2868,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -3011,7 +2888,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -3036,7 +2912,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -3057,7 +2932,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -3078,7 +2952,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -3099,7 +2972,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -3123,7 +2995,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -3144,7 +3015,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -3166,7 +3036,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -3188,7 +3057,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -3209,7 +3077,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -3231,7 +3098,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -3252,7 +3118,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -3273,7 +3138,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -3294,7 +3158,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -3316,7 +3179,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -3337,7 +3199,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -3359,7 +3220,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -3380,7 +3240,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -3401,7 +3260,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -3422,7 +3280,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -3444,7 +3301,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -3465,7 +3321,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -3490,7 +3345,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -3511,7 +3365,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -3532,7 +3385,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -3553,7 +3405,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -3577,7 +3428,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -3598,7 +3448,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -3620,7 +3469,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -3642,7 +3490,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -3663,7 +3510,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -3685,7 +3531,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -3706,7 +3551,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -3727,7 +3571,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -3748,7 +3591,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -3770,7 +3612,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -3791,7 +3632,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -3813,7 +3653,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -3834,7 +3673,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -3855,7 +3693,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -3876,7 +3713,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -3898,7 +3734,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -3919,7 +3754,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -3944,7 +3778,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -3965,7 +3798,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -3986,7 +3818,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -4007,7 +3838,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -4031,7 +3861,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -4052,7 +3881,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -4074,7 +3902,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -4096,7 +3923,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -4117,7 +3943,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -4139,7 +3964,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -4160,7 +3984,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -4181,7 +4004,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -4202,7 +4024,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -4224,7 +4045,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -4245,7 +4065,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -4266,7 +4085,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -4288,7 +4106,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -4309,7 +4126,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -4330,7 +4146,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -4351,7 +4166,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -4373,7 +4187,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -4394,7 +4207,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -4419,7 +4231,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -4440,7 +4251,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -4461,7 +4271,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -4482,7 +4291,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -4506,7 +4314,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -4527,7 +4334,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -4549,7 +4355,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -4571,7 +4376,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -4592,7 +4396,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -4614,7 +4417,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -4635,7 +4437,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -4656,7 +4457,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -4677,7 +4477,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -4699,7 +4498,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -4720,7 +4518,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -4741,7 +4538,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -4763,7 +4559,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -4784,7 +4579,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -4805,7 +4599,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -4826,7 +4619,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -4848,7 +4640,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -4869,7 +4660,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -4894,7 +4684,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -4915,7 +4704,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -4936,7 +4724,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -4957,7 +4744,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -4981,7 +4767,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -5002,7 +4787,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -5024,7 +4808,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -5046,7 +4829,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -5067,7 +4849,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -5089,7 +4870,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -5110,7 +4890,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -5131,7 +4910,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -5152,7 +4930,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -5174,7 +4951,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -5195,7 +4971,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -5217,7 +4992,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -5238,7 +5012,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -5259,7 +5032,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -5280,7 +5052,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -5302,7 +5073,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -5323,7 +5093,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -5349,7 +5118,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -5370,7 +5138,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -5391,7 +5158,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -5412,7 +5178,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -5436,7 +5201,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -5457,7 +5221,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -5479,7 +5242,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -5501,7 +5263,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -5522,7 +5283,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -5544,7 +5304,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -5565,7 +5324,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -5586,7 +5344,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -5607,7 +5364,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -5629,7 +5385,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -5650,7 +5405,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -5672,7 +5426,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -5693,7 +5446,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -5714,7 +5466,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -5735,7 +5486,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -5757,7 +5507,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -5778,7 +5527,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -5805,7 +5553,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -5826,7 +5573,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -5847,7 +5593,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -5868,7 +5613,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -5892,7 +5636,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -5913,7 +5656,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -5935,7 +5677,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -5957,7 +5698,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -5978,7 +5718,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -6000,7 +5739,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -6021,7 +5759,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -6042,7 +5779,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -6063,7 +5799,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -6085,7 +5820,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -6106,7 +5840,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -6127,7 +5860,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -6149,7 +5881,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -6170,7 +5901,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -6191,7 +5921,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -6212,7 +5941,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -6234,7 +5962,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -6255,7 +5982,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -6281,7 +6007,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -6302,7 +6027,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -6323,7 +6047,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -6344,7 +6067,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -6368,7 +6090,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -6389,7 +6110,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -6411,7 +6131,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -6433,7 +6152,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -6454,7 +6172,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -6476,7 +6193,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -6497,7 +6213,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -6518,7 +6233,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -6539,7 +6253,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -6561,7 +6274,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -6582,7 +6294,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -6603,7 +6314,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -6625,7 +6335,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -6646,7 +6355,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -6667,7 +6375,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -6688,7 +6395,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -6710,7 +6416,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -6732,7 +6437,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -6753,7 +6457,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -6780,7 +6483,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -6802,7 +6504,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -6824,7 +6525,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -6846,7 +6546,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -6871,7 +6570,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -6893,7 +6591,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -6916,7 +6613,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -6939,7 +6635,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -6961,7 +6656,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -6984,7 +6678,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -7006,7 +6699,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -7028,7 +6720,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -7050,7 +6741,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -7073,7 +6763,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -7095,7 +6784,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -7118,7 +6806,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -7140,7 +6827,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -7162,7 +6848,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -7184,7 +6869,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -7207,7 +6891,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -7229,7 +6912,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -7256,7 +6938,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -7278,7 +6959,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -7300,7 +6980,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -7322,7 +7001,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -7347,7 +7025,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -7369,7 +7046,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -7392,7 +7068,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -7415,7 +7090,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -7437,7 +7111,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -7460,7 +7133,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -7482,7 +7154,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -7504,7 +7175,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -7526,7 +7196,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -7549,7 +7218,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -7571,7 +7239,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -7594,7 +7261,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -7616,7 +7282,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -7638,7 +7303,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -7660,7 +7324,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -7683,7 +7346,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -7705,7 +7367,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -7731,7 +7392,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -7752,7 +7412,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -7773,7 +7432,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -7794,7 +7452,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -7818,7 +7475,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -7839,7 +7495,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -7861,7 +7516,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -7883,7 +7537,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -7904,7 +7557,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -7926,7 +7578,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -7947,7 +7598,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -7968,7 +7618,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -7989,7 +7638,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -8011,7 +7659,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -8032,7 +7679,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -8054,7 +7700,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -8075,7 +7720,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -8096,7 +7740,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -8117,7 +7760,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -8139,7 +7781,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -8161,7 +7802,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -8182,7 +7822,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -8207,7 +7846,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -8228,7 +7866,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -8249,7 +7886,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -8270,7 +7906,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -8294,7 +7929,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -8315,7 +7949,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -8337,7 +7970,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -8359,7 +7991,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -8380,7 +8011,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -8402,7 +8032,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -8423,7 +8052,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -8444,7 +8072,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -8465,7 +8092,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -8487,7 +8113,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -8508,7 +8133,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -8530,7 +8154,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -8551,7 +8174,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -8572,7 +8194,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -8593,7 +8214,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -8615,7 +8235,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -8636,7 +8255,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -8662,7 +8280,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -8690,7 +8307,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -8711,7 +8327,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -8732,7 +8347,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -8753,7 +8367,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -8777,7 +8390,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -8798,7 +8410,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -8820,7 +8431,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -8842,7 +8452,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -8863,7 +8472,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -8885,7 +8493,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -8906,7 +8513,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -8927,7 +8533,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -8948,7 +8553,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -8970,7 +8574,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -8991,7 +8594,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -9013,7 +8615,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -9034,7 +8635,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -9055,7 +8655,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -9076,7 +8675,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -9098,7 +8696,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -9119,7 +8716,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -9144,7 +8740,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -9165,7 +8760,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -9186,7 +8780,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -9207,7 +8800,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -9231,7 +8823,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -9252,7 +8843,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -9274,7 +8864,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -9296,7 +8885,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -9317,7 +8905,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -9339,7 +8926,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -9360,7 +8946,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -9381,7 +8966,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -9402,7 +8986,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -9424,7 +9007,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -9445,7 +9027,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -9467,7 +9048,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -9488,7 +9068,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -9509,7 +9088,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -9530,7 +9108,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -9552,7 +9129,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -9573,7 +9149,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -9598,7 +9173,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -9619,7 +9193,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -9640,7 +9213,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -9661,7 +9233,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -9685,7 +9256,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -9706,7 +9276,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -9728,7 +9297,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -9750,7 +9318,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -9771,7 +9338,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -9793,7 +9359,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -9814,7 +9379,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -9835,7 +9399,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -9856,7 +9419,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -9878,7 +9440,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -9899,7 +9460,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -9921,7 +9481,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -9942,7 +9501,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -9963,7 +9521,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -9984,7 +9541,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -10006,7 +9562,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -10027,7 +9582,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -10052,7 +9606,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -10073,7 +9626,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -10094,7 +9646,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -10115,7 +9666,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -10139,7 +9689,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -10160,7 +9709,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -10182,7 +9730,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -10204,7 +9751,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -10225,7 +9771,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -10247,7 +9792,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -10268,7 +9812,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -10289,7 +9832,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -10310,7 +9852,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -10332,7 +9873,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -10353,7 +9893,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -10375,7 +9914,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -10396,7 +9934,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -10417,7 +9954,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -10438,7 +9974,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -10460,7 +9995,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -10482,7 +10016,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -10503,7 +10036,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -10540,7 +10072,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 14.5", @@ -10554,7 +10085,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10593,7 +10124,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 15.5", @@ -10607,7 +10137,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10646,7 +10176,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 16.2", @@ -10660,7 +10189,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10698,7 +10227,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 14.5", @@ -10712,7 +10240,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10750,7 +10278,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 15.5", @@ -10764,7 +10291,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10802,7 +10329,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 16.2", @@ -10816,7 +10342,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10854,7 +10380,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 14.5", @@ -10868,7 +10393,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10906,7 +10431,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 15.5", @@ -10920,7 +10444,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -10958,7 +10482,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 16.2", @@ -10972,7 +10495,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11010,7 +10533,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 14.5", @@ -11024,7 +10546,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11062,7 +10584,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 15.5", @@ -11076,7 +10597,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11114,7 +10635,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 16.2", @@ -11128,7 +10648,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11166,7 +10686,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 14.5", @@ -11180,7 +10699,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11218,7 +10737,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 15.5", @@ -11232,7 +10750,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11270,7 +10788,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 16.2", @@ -11284,7 +10801,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11322,7 +10839,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 14.5", @@ -11336,7 +10852,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11375,7 +10891,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 15.5", @@ -11389,7 +10904,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11428,7 +10943,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 16.2", @@ -11442,7 +10956,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11481,7 +10995,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 14.5", @@ -11495,7 +11008,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11535,7 +11048,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 15.5", @@ -11549,7 +11061,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11589,7 +11101,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 16.2", @@ -11603,7 +11114,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11643,7 +11154,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 14.5", @@ -11657,7 +11167,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11695,7 +11205,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 15.5", @@ -11709,7 +11218,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11747,7 +11256,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 16.2", @@ -11761,7 +11269,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11799,7 +11307,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 14.5", @@ -11813,7 +11320,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11851,7 +11358,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 15.5", @@ -11865,7 +11371,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11903,7 +11409,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 16.2", @@ -11917,7 +11422,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -11955,7 +11460,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 14.5", @@ -11969,7 +11473,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12007,7 +11511,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 15.5", @@ -12021,7 +11524,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12059,7 +11562,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 16.2", @@ -12073,7 +11575,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12111,7 +11613,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 14.5", @@ -12125,7 +11626,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12164,7 +11665,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 15.5", @@ -12178,7 +11678,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12217,7 +11717,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 16.2", @@ -12231,7 +11730,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12271,7 +11770,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 14.5", @@ -12285,7 +11783,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12324,7 +11822,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 15.5", @@ -12338,7 +11835,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12377,7 +11874,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 16.2", @@ -12391,7 +11887,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12430,7 +11926,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 14.5", @@ -12444,7 +11939,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12483,7 +11978,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 15.5", @@ -12497,7 +11991,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12536,7 +12030,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 16.2", @@ -12550,7 +12043,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12588,7 +12081,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 14.5", @@ -12602,7 +12094,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12642,7 +12134,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 15.5", @@ -12656,7 +12147,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12696,7 +12187,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 16.2", @@ -12710,7 +12200,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12750,7 +12240,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 14.5", @@ -12764,7 +12253,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12802,7 +12291,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 15.5", @@ -12816,7 +12304,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12854,7 +12342,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 16.2", @@ -12868,7 +12355,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12906,7 +12393,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 14.5", @@ -12920,7 +12406,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -12958,7 +12444,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 15.5", @@ -12972,7 +12457,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13010,7 +12495,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 16.2", @@ -13024,7 +12508,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13062,7 +12546,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 14.5", @@ -13076,7 +12559,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13114,7 +12597,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 15.5", @@ -13128,7 +12610,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13166,7 +12648,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 16.2", @@ -13180,7 +12661,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13218,7 +12699,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 14.5", @@ -13232,7 +12712,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13270,7 +12750,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 15.5", @@ -13284,7 +12763,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13322,7 +12801,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 16.2", @@ -13336,7 +12814,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13374,7 +12852,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 14.5", @@ -13388,7 +12865,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13427,7 +12904,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 15.5", @@ -13441,7 +12917,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13480,7 +12956,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 16.2", @@ -13494,7 +12969,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13533,7 +13008,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 14.5", @@ -13547,7 +13021,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13585,7 +13059,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 15.5", @@ -13599,7 +13072,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13637,7 +13110,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 16.2", @@ -13651,7 +13123,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13689,7 +13161,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 14.5", @@ -13703,7 +13174,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13741,7 +13212,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 15.5", @@ -13755,7 +13225,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -13793,7 +13263,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 16.2", @@ -13807,7 +13276,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ diff --git a/third_party/libwebrtc/infra/specs/internal.client.webrtc.json b/third_party/libwebrtc/infra/specs/internal.client.webrtc.json index fa3c96d157d9a..9fcb9225e7716 100644 --- a/third_party/libwebrtc/infra/specs/internal.client.webrtc.json +++ b/third_party/libwebrtc/infra/specs/internal.client.webrtc.json @@ -13,7 +13,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -27,7 +26,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -56,7 +55,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -70,7 +68,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -100,7 +98,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -114,7 +111,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -146,7 +143,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -160,7 +156,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -190,7 +186,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -204,7 +199,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -233,7 +228,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -247,7 +241,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -276,7 +270,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -290,7 +283,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -319,7 +312,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -333,7 +325,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -362,7 +354,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -376,7 +367,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -405,7 +396,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -419,7 +409,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -448,7 +438,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -462,7 +451,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -515,12 +504,12 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ { - "id": "build15-a7", + "id": "mac-254-e504", "os": "iOS-12.4.1", "pool": "WebRTC" } @@ -552,7 +541,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -566,7 +554,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -595,7 +583,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -609,7 +596,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -639,7 +626,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -653,7 +639,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -685,7 +671,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -699,7 +684,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -729,7 +714,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -743,7 +727,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -772,7 +756,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -786,7 +769,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -815,7 +798,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -829,7 +811,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -858,7 +840,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -872,7 +853,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -901,7 +882,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -915,7 +895,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -944,7 +924,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -958,7 +937,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -987,7 +966,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -1001,7 +979,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ diff --git a/third_party/libwebrtc/infra/specs/mixins.pyl b/third_party/libwebrtc/infra/specs/mixins.pyl index f46c487426cbe..e8b94ee141f0e 100644 --- a/third_party/libwebrtc/infra/specs/mixins.pyl +++ b/third_party/libwebrtc/infra/specs/mixins.pyl @@ -80,7 +80,7 @@ 'dimensions': { 'os': 'iOS-12.4.1', 'pool': 'WebRTC', - 'id': 'build15-a7' + 'id': 'mac-254-e504' } } }, @@ -174,7 +174,7 @@ 'location': '.', 'revision': - 'git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1' + 'git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118' }] } }, diff --git a/third_party/libwebrtc/infra/specs/mixins_webrtc.pyl b/third_party/libwebrtc/infra/specs/mixins_webrtc.pyl index 238c69d44e8c2..c29af11e55d00 100644 --- a/third_party/libwebrtc/infra/specs/mixins_webrtc.pyl +++ b/third_party/libwebrtc/infra/specs/mixins_webrtc.pyl @@ -60,10 +60,20 @@ 'dimensions': { 'os': 'iOS-12.4.1', 'pool': 'WebRTC', - 'id': 'build15-a7', + 'id': 'mac-254-e504', }, }, }, + 'ios_runtime_cache_14_5': { + '$mixin_append': { + 'swarming': { + 'named_caches': [{ + 'name': 'runtime_ios_14_5', + 'path': 'Runtime-ios-14.5' + }] + } + } + }, 'limited-capacity': { # Sometimes there are multiple tests that can be run only on one machine. # We need to increase timeouts so the tests dont expire before the machine is freed. diff --git a/third_party/libwebrtc/infra/specs/tryserver.webrtc.json b/third_party/libwebrtc/infra/specs/tryserver.webrtc.json index b682dfabf4f69..9ad0d7e5ee7c8 100644 --- a/third_party/libwebrtc/infra/specs/tryserver.webrtc.json +++ b/third_party/libwebrtc/infra/specs/tryserver.webrtc.json @@ -5,7 +5,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -28,7 +27,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -51,7 +49,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -74,7 +71,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -97,7 +93,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -120,7 +115,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -143,7 +137,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -167,7 +160,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -191,7 +183,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -214,7 +205,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -238,7 +228,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -261,7 +250,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -284,7 +272,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -307,7 +294,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -331,7 +317,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -354,7 +339,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -378,7 +362,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -401,7 +384,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -424,7 +406,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -447,7 +428,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -471,7 +451,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -494,7 +473,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -521,7 +499,6 @@ "--nologs" ], "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -570,7 +547,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -593,7 +569,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -616,7 +591,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -639,7 +613,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -662,7 +635,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -685,7 +657,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -708,7 +679,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -732,7 +702,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -756,7 +725,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -779,7 +747,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -803,7 +770,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -826,7 +792,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -849,7 +814,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -872,7 +836,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -896,7 +859,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -919,7 +881,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -943,7 +904,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -966,7 +926,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -989,7 +948,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1012,7 +970,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1036,7 +993,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1059,7 +1015,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1086,7 +1041,6 @@ "--nologs" ], "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1135,7 +1089,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1158,7 +1111,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1181,7 +1133,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1204,7 +1155,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1227,7 +1177,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1250,7 +1199,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1273,7 +1221,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1297,7 +1244,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1321,7 +1267,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1344,7 +1289,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1368,7 +1312,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1391,7 +1334,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1414,7 +1356,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1437,7 +1378,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1461,7 +1401,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1484,7 +1423,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1508,7 +1446,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1531,7 +1468,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1554,7 +1490,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1577,7 +1512,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1601,7 +1535,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1624,7 +1557,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1651,7 +1583,6 @@ "--nologs" ], "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1700,7 +1631,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1728,7 +1658,6 @@ "gtest_tests": [ { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1751,7 +1680,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1774,7 +1702,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1797,7 +1724,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1820,7 +1746,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1843,7 +1768,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1866,7 +1790,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1890,7 +1813,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1914,7 +1836,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1937,7 +1858,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1961,7 +1881,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -1984,7 +1903,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2007,7 +1925,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2030,7 +1947,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2054,7 +1970,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2077,7 +1992,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2101,7 +2015,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2124,7 +2037,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2147,7 +2059,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2170,7 +2081,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2194,7 +2104,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2217,7 +2126,6 @@ }, { "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2244,7 +2152,6 @@ "--nologs" ], "merge": { - "args": [], "script": "//testing/merge_scripts/standard_gtest_merge.py" }, "resultdb": { @@ -2308,7 +2215,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -2336,7 +2242,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -2364,7 +2269,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -2392,7 +2296,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -2421,7 +2324,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -2449,7 +2351,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -2477,7 +2378,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -2505,7 +2405,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -2534,7 +2433,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -2562,7 +2460,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -2591,7 +2488,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -2619,7 +2515,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -2659,7 +2554,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 14.5", @@ -2673,7 +2567,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2712,7 +2606,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 15.5", @@ -2726,7 +2619,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2765,7 +2658,6 @@ ], "isolate_name": "apprtcmobile_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "apprtcmobile_tests iPhone X 16.2", @@ -2779,7 +2671,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2817,7 +2709,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 14.5", @@ -2831,7 +2722,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2869,7 +2760,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 15.5", @@ -2883,7 +2773,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2921,7 +2811,6 @@ ], "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests iPhone X 16.2", @@ -2935,7 +2824,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -2973,7 +2862,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 14.5", @@ -2987,7 +2875,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3025,7 +2913,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 15.5", @@ -3039,7 +2926,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3077,7 +2964,6 @@ ], "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests iPhone X 16.2", @@ -3091,7 +2977,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3129,7 +3015,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 14.5", @@ -3143,7 +3028,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3181,7 +3066,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 15.5", @@ -3195,7 +3079,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3233,7 +3117,6 @@ ], "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests iPhone X 16.2", @@ -3247,7 +3130,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3285,7 +3168,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 14.5", @@ -3299,7 +3181,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3337,7 +3219,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 15.5", @@ -3351,7 +3232,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3389,7 +3270,6 @@ ], "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests iPhone X 16.2", @@ -3403,7 +3283,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3441,7 +3321,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 14.5", @@ -3455,7 +3334,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3494,7 +3373,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 15.5", @@ -3508,7 +3386,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3547,7 +3425,6 @@ ], "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests iPhone X 16.2", @@ -3561,7 +3438,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3600,7 +3477,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 14.5", @@ -3614,7 +3490,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3654,7 +3530,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 15.5", @@ -3668,7 +3543,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3708,7 +3583,6 @@ ], "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests iPhone X 16.2", @@ -3722,7 +3596,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3762,7 +3636,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 14.5", @@ -3776,7 +3649,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3814,7 +3687,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 15.5", @@ -3828,7 +3700,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3866,7 +3738,6 @@ ], "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests iPhone X 16.2", @@ -3880,7 +3751,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3918,7 +3789,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 14.5", @@ -3932,7 +3802,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -3970,7 +3840,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 15.5", @@ -3984,7 +3853,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4022,7 +3891,6 @@ ], "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests iPhone X 16.2", @@ -4036,7 +3904,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4074,7 +3942,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 14.5", @@ -4088,7 +3955,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4126,7 +3993,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 15.5", @@ -4140,7 +4006,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4178,7 +4044,6 @@ ], "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests iPhone X 16.2", @@ -4192,7 +4057,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4230,7 +4095,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 14.5", @@ -4244,7 +4108,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4283,7 +4147,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 15.5", @@ -4297,7 +4160,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4336,7 +4199,6 @@ ], "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests iPhone X 16.2", @@ -4350,7 +4212,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4390,7 +4252,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 14.5", @@ -4404,7 +4265,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4443,7 +4304,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 15.5", @@ -4457,7 +4317,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4496,7 +4356,6 @@ ], "isolate_name": "sdk_framework_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_framework_unittests iPhone X 16.2", @@ -4510,7 +4369,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4549,7 +4408,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 14.5", @@ -4563,7 +4421,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4602,7 +4460,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 15.5", @@ -4616,7 +4473,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4655,7 +4512,6 @@ ], "isolate_name": "sdk_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "sdk_unittests iPhone X 16.2", @@ -4669,7 +4525,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4707,7 +4563,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 14.5", @@ -4721,7 +4576,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4761,7 +4616,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 15.5", @@ -4775,7 +4629,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4815,7 +4669,6 @@ ], "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests iPhone X 16.2", @@ -4829,7 +4682,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4869,7 +4722,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 14.5", @@ -4883,7 +4735,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4921,7 +4773,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 15.5", @@ -4935,7 +4786,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -4973,7 +4824,6 @@ ], "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests iPhone X 16.2", @@ -4987,7 +4837,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5025,7 +4875,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 14.5", @@ -5039,7 +4888,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5077,7 +4926,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 15.5", @@ -5091,7 +4939,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5129,7 +4977,6 @@ ], "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests iPhone X 16.2", @@ -5143,7 +4990,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5181,7 +5028,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 14.5", @@ -5195,7 +5041,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5233,7 +5079,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 15.5", @@ -5247,7 +5092,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5285,7 +5130,6 @@ ], "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests iPhone X 16.2", @@ -5299,7 +5143,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5337,7 +5181,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 14.5", @@ -5351,7 +5194,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5389,7 +5232,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 15.5", @@ -5403,7 +5245,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5441,7 +5283,6 @@ ], "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests iPhone X 16.2", @@ -5455,7 +5296,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5493,7 +5334,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 14.5", @@ -5507,7 +5347,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5546,7 +5386,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 15.5", @@ -5560,7 +5399,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5599,7 +5438,6 @@ ], "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests iPhone X 16.2", @@ -5613,7 +5451,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5652,7 +5490,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 14.5", @@ -5666,7 +5503,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5704,7 +5541,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 15.5", @@ -5718,7 +5554,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5756,7 +5592,6 @@ ], "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests iPhone X 16.2", @@ -5770,7 +5605,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5808,7 +5643,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 14.5", @@ -5822,7 +5656,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5860,7 +5694,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 15.5", @@ -5874,7 +5707,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5912,7 +5745,6 @@ ], "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests iPhone X 16.2", @@ -5926,7 +5758,7 @@ { "cipd_package": "infra/tools/mac_toolchain/${platform}", "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" + "revision": "git_revision:a598cd77abc01089647a79e3cfa3cc8e8ecb5118" } ], "dimension_sets": [ @@ -5957,7 +5789,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -5978,7 +5809,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -5999,7 +5829,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -6020,7 +5849,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -6044,7 +5872,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -6065,7 +5892,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -6087,7 +5913,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -6109,7 +5934,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -6130,7 +5954,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -6152,7 +5975,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -6173,7 +5995,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -6194,7 +6015,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -6215,7 +6035,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -6237,7 +6056,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -6258,7 +6076,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -6279,7 +6096,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -6301,7 +6117,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -6322,7 +6137,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -6343,7 +6157,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -6364,7 +6177,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -6386,7 +6198,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -6407,7 +6218,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -6439,7 +6249,6 @@ "isolate_name": "audio_decoder_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -6461,7 +6270,6 @@ "isolate_name": "common_audio_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -6483,7 +6291,6 @@ "isolate_name": "common_video_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -6505,7 +6312,6 @@ "isolate_name": "dcsctp_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -6530,7 +6336,6 @@ "isolate_name": "low_bandwidth_audio_test", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -6552,7 +6357,6 @@ "isolate_name": "modules_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -6575,7 +6379,6 @@ "isolate_name": "modules_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -6598,7 +6401,6 @@ "isolate_name": "peer_connection_mediachannel_split_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -6620,7 +6422,6 @@ "isolate_name": "peerconnection_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -6643,7 +6444,6 @@ "isolate_name": "rtc_media_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -6665,7 +6465,6 @@ "isolate_name": "rtc_pc_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -6687,7 +6486,6 @@ "isolate_name": "rtc_stats_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -6709,7 +6507,6 @@ "isolate_name": "rtc_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -6732,7 +6529,6 @@ "isolate_name": "shared_screencast_stream_test", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -6754,7 +6550,6 @@ "isolate_name": "slow_peer_connection_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -6776,7 +6571,6 @@ "isolate_name": "svc_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -6799,7 +6593,6 @@ "isolate_name": "system_wrappers_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -6821,7 +6614,6 @@ "isolate_name": "test_support_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -6843,7 +6635,6 @@ "isolate_name": "tools_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -6865,7 +6656,6 @@ "isolate_name": "video_capture_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -6888,7 +6678,6 @@ "isolate_name": "video_engine_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -6911,7 +6700,6 @@ "isolate_name": "voip_unittests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -6933,7 +6721,6 @@ "isolate_name": "webrtc_nonparallel_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -6960,7 +6747,6 @@ "isolate_name": "webrtc_perf_tests", "isolate_profile_data": true, "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_perf_tests", @@ -6986,7 +6772,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -7007,7 +6792,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -7028,7 +6812,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -7049,7 +6832,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -7073,7 +6855,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -7094,7 +6875,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -7116,7 +6896,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -7138,7 +6917,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -7159,7 +6937,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -7181,7 +6958,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -7202,7 +6978,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -7223,7 +6998,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -7244,7 +7018,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -7266,7 +7039,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -7287,7 +7059,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -7308,7 +7079,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -7330,7 +7100,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -7351,7 +7120,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -7372,7 +7140,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -7393,7 +7160,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -7415,7 +7181,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -7436,7 +7201,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -7462,7 +7226,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -7483,7 +7246,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -7504,7 +7266,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -7525,7 +7286,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -7549,7 +7309,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -7570,7 +7329,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -7592,7 +7350,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -7614,7 +7371,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -7635,7 +7391,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -7657,7 +7412,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -7678,7 +7432,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -7699,7 +7452,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -7720,7 +7472,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -7742,7 +7493,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -7763,7 +7513,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -7784,7 +7533,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -7806,7 +7554,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -7827,7 +7574,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -7848,7 +7594,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -7869,7 +7614,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -7891,7 +7635,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -7912,7 +7655,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -7937,7 +7679,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -7963,7 +7704,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -7984,7 +7724,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -8005,7 +7744,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -8026,7 +7764,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -8050,7 +7787,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -8071,7 +7807,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -8093,7 +7828,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -8115,7 +7849,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -8136,7 +7869,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -8158,7 +7890,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -8179,7 +7910,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -8200,7 +7930,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -8221,7 +7950,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -8243,7 +7971,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -8264,7 +7991,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -8286,7 +8012,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -8307,7 +8032,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -8328,7 +8052,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -8349,7 +8072,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -8371,7 +8093,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -8392,7 +8113,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -8417,7 +8137,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -8438,7 +8157,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -8459,7 +8177,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -8480,7 +8197,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -8504,7 +8220,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -8525,7 +8240,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -8547,7 +8261,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -8569,7 +8282,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -8590,7 +8302,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -8612,7 +8323,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -8633,7 +8343,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -8654,7 +8363,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -8675,7 +8383,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -8697,7 +8404,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -8718,7 +8424,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -8739,7 +8444,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -8761,7 +8465,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -8782,7 +8485,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -8803,7 +8505,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -8824,7 +8525,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -8846,7 +8546,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -8868,7 +8567,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -8889,7 +8587,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -8915,7 +8612,6 @@ ], "isolate_name": "webrtc_perf_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_perf_tests", @@ -8941,7 +8637,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -8962,7 +8657,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -8983,7 +8677,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -9004,7 +8697,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -9028,7 +8720,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -9049,7 +8740,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -9071,7 +8761,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -9093,7 +8782,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -9114,7 +8802,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -9136,7 +8823,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -9157,7 +8843,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -9178,7 +8863,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -9199,7 +8883,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -9221,7 +8904,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -9242,7 +8924,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -9264,7 +8945,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -9285,7 +8965,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -9306,7 +8985,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -9327,7 +9005,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -9349,7 +9026,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -9370,7 +9046,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -9395,7 +9070,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -9416,7 +9090,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -9437,7 +9110,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -9458,7 +9130,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -9482,7 +9153,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -9503,7 +9173,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -9525,7 +9194,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -9547,7 +9215,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -9568,7 +9235,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -9590,7 +9256,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -9611,7 +9276,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -9632,7 +9296,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -9653,7 +9316,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -9675,7 +9337,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -9696,7 +9357,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -9717,7 +9377,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -9739,7 +9398,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -9760,7 +9418,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -9781,7 +9438,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -9802,7 +9458,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -9824,7 +9479,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -9845,7 +9499,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -9870,7 +9523,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -9891,7 +9543,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -9912,7 +9563,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -9933,7 +9583,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -9957,7 +9606,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -9978,7 +9626,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -10000,7 +9647,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -10022,7 +9668,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -10043,7 +9688,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -10065,7 +9709,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -10086,7 +9729,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -10107,7 +9749,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -10128,7 +9769,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -10150,7 +9790,6 @@ { "isolate_name": "shared_screencast_stream_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "shared_screencast_stream_test", @@ -10171,7 +9810,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -10192,7 +9830,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -10214,7 +9851,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -10235,7 +9871,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -10256,7 +9891,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -10277,7 +9911,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -10299,7 +9932,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -10320,7 +9952,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -10345,7 +9976,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -10366,7 +9996,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -10387,7 +10016,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -10408,7 +10036,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -10432,7 +10059,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -10453,7 +10079,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -10475,7 +10100,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -10497,7 +10121,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -10518,7 +10141,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -10540,7 +10162,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -10561,7 +10182,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -10582,7 +10202,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -10603,7 +10222,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -10625,7 +10243,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -10646,7 +10263,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -10668,7 +10284,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -10689,7 +10304,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -10710,7 +10324,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -10731,7 +10344,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -10753,7 +10365,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -10774,7 +10385,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -10799,7 +10409,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -10820,7 +10429,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -10841,7 +10449,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -10862,7 +10469,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -10886,7 +10492,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -10907,7 +10512,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -10929,7 +10533,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -10951,7 +10554,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -10972,7 +10574,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -10994,7 +10595,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -11015,7 +10615,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -11036,7 +10635,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -11057,7 +10655,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -11079,7 +10676,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -11100,7 +10696,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -11122,7 +10717,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -11143,7 +10737,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -11164,7 +10757,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -11185,7 +10777,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -11207,7 +10798,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -11228,7 +10818,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -11253,7 +10842,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -11275,7 +10863,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -11297,7 +10884,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -11319,7 +10905,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -11344,7 +10929,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -11366,7 +10950,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -11389,7 +10972,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -11412,7 +10994,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -11434,7 +11015,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -11457,7 +11037,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -11479,7 +11058,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -11501,7 +11079,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -11523,7 +11100,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -11546,7 +11122,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -11568,7 +11143,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -11591,7 +11165,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -11613,7 +11186,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -11635,7 +11207,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -11657,7 +11228,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -11680,7 +11250,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -11702,7 +11271,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -11730,7 +11298,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -11752,7 +11319,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -11774,7 +11340,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -11796,7 +11361,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -11821,7 +11385,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -11843,7 +11406,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -11866,7 +11428,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -11889,7 +11450,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -11911,7 +11471,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -11934,7 +11493,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -11956,7 +11514,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -11978,7 +11535,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -12000,7 +11556,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -12023,7 +11578,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -12045,7 +11599,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -12068,7 +11621,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -12090,7 +11642,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -12112,7 +11663,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -12134,7 +11684,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -12157,7 +11706,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -12179,7 +11727,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -12205,7 +11752,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -12226,7 +11772,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -12247,7 +11792,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -12268,7 +11812,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -12292,7 +11835,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -12313,7 +11855,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -12335,7 +11876,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -12357,7 +11897,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -12378,7 +11917,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -12400,7 +11938,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -12421,7 +11958,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -12442,7 +11978,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -12463,7 +11998,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -12485,7 +12019,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -12506,7 +12039,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -12528,7 +12060,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -12549,7 +12080,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -12570,7 +12100,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -12591,7 +12120,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -12613,7 +12141,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -12634,7 +12161,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -12659,7 +12185,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -12680,7 +12205,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -12701,7 +12225,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -12722,7 +12245,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -12746,7 +12268,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -12767,7 +12288,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -12789,7 +12309,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -12811,7 +12330,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -12832,7 +12350,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -12854,7 +12371,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -12875,7 +12391,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -12896,7 +12411,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -12917,7 +12431,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -12939,7 +12452,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -12960,7 +12472,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -12982,7 +12493,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -13003,7 +12513,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -13024,7 +12533,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -13045,7 +12553,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -13067,7 +12574,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -13089,7 +12595,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -13110,7 +12615,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -13136,7 +12640,6 @@ ], "isolate_name": "webrtc_perf_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_perf_tests", @@ -13162,7 +12665,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -13183,7 +12685,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -13204,7 +12705,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -13225,7 +12725,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -13249,7 +12748,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -13270,7 +12768,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -13292,7 +12789,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -13314,7 +12810,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -13335,7 +12830,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -13357,7 +12851,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -13378,7 +12871,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -13399,7 +12891,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -13420,7 +12911,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -13442,7 +12932,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -13463,7 +12952,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -13485,7 +12973,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -13506,7 +12993,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -13527,7 +13013,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -13548,7 +13033,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -13570,7 +13054,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -13591,7 +13074,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -13616,7 +13098,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -13637,7 +13118,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -13658,7 +13138,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -13679,7 +13158,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -13703,7 +13181,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -13724,7 +13201,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -13746,7 +13222,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -13768,7 +13243,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -13789,7 +13263,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -13811,7 +13284,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -13832,7 +13304,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -13853,7 +13324,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -13874,7 +13344,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -13896,7 +13365,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -13917,7 +13385,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -13939,7 +13406,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -13960,7 +13426,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -13981,7 +13446,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -14002,7 +13466,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -14024,7 +13487,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -14045,7 +13507,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -14074,7 +13535,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -14095,7 +13555,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -14116,7 +13575,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -14137,7 +13595,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -14161,7 +13618,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -14182,7 +13638,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -14204,7 +13659,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -14226,7 +13680,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -14247,7 +13700,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -14269,7 +13721,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -14290,7 +13741,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -14311,7 +13761,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -14332,7 +13781,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -14354,7 +13802,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -14375,7 +13822,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -14397,7 +13843,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -14418,7 +13863,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -14439,7 +13883,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -14460,7 +13903,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -14482,7 +13924,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -14503,7 +13944,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -14528,7 +13968,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -14549,7 +13988,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -14570,7 +14008,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -14591,7 +14028,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -14615,7 +14051,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -14636,7 +14071,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -14658,7 +14092,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -14680,7 +14113,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -14701,7 +14133,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -14723,7 +14154,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -14744,7 +14174,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -14765,7 +14194,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -14786,7 +14214,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -14808,7 +14235,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -14829,7 +14255,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -14851,7 +14276,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -14872,7 +14296,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -14893,7 +14316,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -14914,7 +14336,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -14936,7 +14357,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -14957,7 +14377,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -14982,7 +14401,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -15003,7 +14421,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -15024,7 +14441,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -15045,7 +14461,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -15069,7 +14484,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -15090,7 +14504,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -15112,7 +14525,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -15134,7 +14546,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -15155,7 +14566,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -15177,7 +14587,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -15198,7 +14607,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -15219,7 +14627,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -15240,7 +14647,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -15262,7 +14668,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -15283,7 +14688,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -15305,7 +14709,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -15326,7 +14729,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -15347,7 +14749,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -15368,7 +14769,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -15390,7 +14790,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -15411,7 +14810,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -15436,7 +14834,6 @@ { "isolate_name": "audio_decoder_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "audio_decoder_unittests", @@ -15457,7 +14854,6 @@ { "isolate_name": "common_audio_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_audio_unittests", @@ -15478,7 +14874,6 @@ { "isolate_name": "common_video_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "common_video_unittests", @@ -15499,7 +14894,6 @@ { "isolate_name": "dcsctp_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "dcsctp_unittests", @@ -15523,7 +14917,6 @@ ], "isolate_name": "low_bandwidth_audio_test", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "low_bandwidth_audio_test", @@ -15544,7 +14937,6 @@ { "isolate_name": "modules_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_tests", @@ -15566,7 +14958,6 @@ { "isolate_name": "modules_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "modules_unittests", @@ -15588,7 +14979,6 @@ { "isolate_name": "peer_connection_mediachannel_split_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peer_connection_mediachannel_split_unittests", @@ -15609,7 +14999,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", @@ -15631,7 +15020,6 @@ { "isolate_name": "rtc_media_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_media_unittests", @@ -15652,7 +15040,6 @@ { "isolate_name": "rtc_pc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_pc_unittests", @@ -15673,7 +15060,6 @@ { "isolate_name": "rtc_stats_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_stats_unittests", @@ -15694,7 +15080,6 @@ { "isolate_name": "rtc_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "rtc_unittests", @@ -15716,7 +15101,6 @@ { "isolate_name": "slow_peer_connection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "slow_peer_connection_unittests", @@ -15737,7 +15121,6 @@ { "isolate_name": "svc_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "svc_tests", @@ -15759,7 +15142,6 @@ { "isolate_name": "system_wrappers_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "system_wrappers_unittests", @@ -15780,7 +15162,6 @@ { "isolate_name": "test_support_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "test_support_unittests", @@ -15801,7 +15182,6 @@ { "isolate_name": "tools_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "tools_unittests", @@ -15822,7 +15202,6 @@ { "isolate_name": "video_capture_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_capture_tests", @@ -15844,7 +15223,6 @@ { "isolate_name": "video_engine_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "video_engine_tests", @@ -15866,7 +15244,6 @@ { "isolate_name": "voip_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "voip_unittests", @@ -15887,7 +15264,6 @@ { "isolate_name": "webrtc_nonparallel_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_nonparallel_tests", @@ -15913,7 +15289,6 @@ ], "isolate_name": "webrtc_perf_tests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "webrtc_perf_tests", @@ -15939,7 +15314,6 @@ { "isolate_name": "peerconnection_unittests", "merge": { - "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, "name": "peerconnection_unittests", diff --git a/third_party/libwebrtc/logging/BUILD.gn b/third_party/libwebrtc/logging/BUILD.gn index 71cb41327f1f3..c7b020f7fe8e0 100644 --- a/third_party/libwebrtc/logging/BUILD.gn +++ b/third_party/libwebrtc/logging/BUILD.gn @@ -625,6 +625,8 @@ if (rtc_enable_protobuf) { "../rtc_base:rtc_base_tests_utils", "../rtc_base:timeutils", "../system_wrappers", + "../system_wrappers:field_trial", + "../test:field_trial", "../test:fileutils", "../test:test_support", "../test/logging:log_writer", diff --git a/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index 2e02f682138f4..5d83c72a0b4b8 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -13,6 +13,7 @@ #include "absl/types/optional.h" #include "api/array_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" #include "logging/rtc_event_log/encoder/delta_encoding.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h" @@ -56,6 +57,7 @@ #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h" #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet.h" #include "rtc_base/checks.h" @@ -147,6 +149,8 @@ bool ConvertToProtoFormat(const std::vector& extensions, proto_config->set_transport_sequence_number_id(extension.id); } else if (extension.uri == RtpExtension::kVideoRotationUri) { proto_config->set_video_rotation_id(extension.id); + } else if (extension.uri == RtpExtension::kDependencyDescriptorUri) { + proto_config->set_dependency_descriptor_id(extension.id); } else { ++unknown_extensions; } @@ -457,6 +461,29 @@ 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")) { + std::vector> raw_dds(batch.size()); + bool has_dd = false; + for (size_t i = 0; i < batch.size(); ++i) { + raw_dds[i] = + batch[i] + ->template GetRawExtension(); + has_dd |= !raw_dds[i].empty(); + } + if (has_dd) { + if (auto dd_encoded = + RtcEventLogDependencyDescriptorEncoderDecoder::Encode( + raw_dds)) { + *proto_batch->mutable_dependency_descriptor() = *dd_encoded; + } + } + } + } + if (batch.size() == 1) { return; } diff --git a/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc index 7039fe7eb65d5..612f85bf6187d 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc +++ b/third_party/libwebrtc/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -40,6 +40,7 @@ #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "rtc_base/fake_clock.h" #include "rtc_base/random.h" +#include "test/field_trial.h" #include "test/gtest.h" namespace webrtc { @@ -1291,6 +1292,20 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) { TestRtpPackets(); } +TEST_P(RtcEventLogEncoderTest, + RtcEventRtpPacketIncomingNoDependencyDescriptor) { + test::ScopedFieldTrials no_dd( + "WebRTC-RtcEventLogEncodeDependencyDescriptor/Disabled/"); + TestRtpPackets(); +} + +TEST_P(RtcEventLogEncoderTest, + RtcEventRtpPacketOutgoingNoDependencyDescriptor) { + test::ScopedFieldTrials no_dd( + "WebRTC-RtcEventLogEncodeDependencyDescriptor/Disabled/"); + TestRtpPackets(); +} + // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) { uint32_t ssrc = prng_.Rand(); diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h b/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h index c441dea1a483f..fe5fcfd765e31 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h +++ b/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h @@ -47,6 +47,8 @@ struct LoggedRtpPacket { Timestamp timestamp; // TODO(terelius): This allocates space for 15 CSRCs even if none are used. RTPHeader header; + // RTPHeader::extension is a mess, save DD wire format instead. + std::vector dependency_descriptor_wire_format; size_t header_length; size_t total_length; }; diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h index 926ddddff5898..66ea167a1c28e 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h +++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h @@ -57,6 +57,10 @@ class RtcEventRtpPacketIncoming final : public RtcEvent { return packet_.GetExtension(std::forward(args)...); } template + rtc::ArrayView GetRawExtension() const { + return packet_.GetRawExtension(); + } + template bool HasExtension() const { return packet_.HasExtension(); } diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h index c7b7a09718c2f..4f4be04445b0a 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h +++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h @@ -58,6 +58,10 @@ class RtcEventRtpPacketOutgoing final : public RtcEvent { return packet_.GetExtension(std::forward(args)...); } template + rtc::ArrayView GetRawExtension() const { + return packet_.GetRawExtension(); + } + template bool HasExtension() const { return packet_.HasExtension(); } diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log2.proto b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log2.proto index 1cf5a06ebe0c6..658df6b6ff171 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log2.proto +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log2.proto @@ -453,6 +453,7 @@ message RtpHeaderExtensionConfig { optional int32 transport_sequence_number_id = 3; optional int32 video_rotation_id = 4; optional int32 audio_level_id = 5; + optional int32 dependency_descriptor_id = 6; // TODO(terelius): Add other header extensions like playout delay? } diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.cc b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.cc index a5e901d8ac61d..75f2fdebcf689 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_parser.cc @@ -25,6 +25,7 @@ #include "api/rtc_event_log/rtc_event_log.h" #include "api/rtp_headers.h" #include "api/rtp_parameters.h" +#include "logging/rtc_event_log/dependency_descriptor_encoder_decoder.h" #include "logging/rtc_event_log/encoder/blob_encoding.h" #include "logging/rtc_event_log/encoder/delta_encoding.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h" @@ -35,6 +36,7 @@ #include "modules/rtp_rtcp/include/rtp_cvo.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/byte_io.h" +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "rtc_base/checks.h" @@ -297,6 +299,22 @@ ParsedRtcEventLog::ParseStatus StoreRtpPackets( RTC_PARSE_CHECK_OR_RETURN(proto.has_header_size()); RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_size()); + const size_t number_of_deltas = + proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u; + const size_t total_packets = number_of_deltas + 1; + + std::vector> dependency_descriptor_wire_format( + total_packets); + if (proto.has_dependency_descriptor()) { + auto status_or_decoded = + RtcEventLogDependencyDescriptorEncoderDecoder::Decode( + proto.dependency_descriptor(), total_packets); + if (!status_or_decoded.ok()) { + return status_or_decoded.status(); + } + dependency_descriptor_wire_format = status_or_decoded.value(); + } + // Base event { RTPHeader header; @@ -342,13 +360,16 @@ ParsedRtcEventLog::ParseStatus StoreRtpPackets( } else { RTC_PARSE_CHECK_OR_RETURN(!proto.has_voice_activity()); } - (*rtp_packets_map)[header.ssrc].emplace_back( + LoggedType logged_packet( Timestamp::Millis(proto.timestamp_ms()), header, proto.header_size(), proto.payload_size() + header.headerLength + header.paddingLength); + if (!dependency_descriptor_wire_format[0].empty()) { + logged_packet.rtp.dependency_descriptor_wire_format = + dependency_descriptor_wire_format[0]; + } + (*rtp_packets_map)[header.ssrc].push_back(std::move(logged_packet)); } - const size_t number_of_deltas = - proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u; if (number_of_deltas == 0) { return ParsedRtcEventLog::ParseStatus::Success(); } @@ -544,10 +565,15 @@ ParsedRtcEventLog::ParseStatus StoreRtpPackets( RTC_PARSE_CHECK_OR_RETURN(voice_activity_values.size() <= i || !voice_activity_values[i].has_value()); } - (*rtp_packets_map)[header.ssrc].emplace_back( - Timestamp::Millis(timestamp_ms), header, header.headerLength, - payload_size_values[i].value() + header.headerLength + - header.paddingLength); + LoggedType logged_packet(Timestamp::Millis(timestamp_ms), header, + header.headerLength, + payload_size_values[i].value() + + header.headerLength + header.paddingLength); + if (!dependency_descriptor_wire_format[i + 1].empty()) { + logged_packet.rtp.dependency_descriptor_wire_format = + dependency_descriptor_wire_format[i + 1]; + } + (*rtp_packets_map)[header.ssrc].push_back(std::move(logged_packet)); } return ParsedRtcEventLog::ParseStatus::Success(); } @@ -888,6 +914,11 @@ std::vector GetRuntimeRtpHeaderExtensionConfig( rtp_extensions.emplace_back(RtpExtension::kVideoRotationUri, proto_header_extensions.video_rotation_id()); } + if (proto_header_extensions.has_dependency_descriptor_id()) { + rtp_extensions.emplace_back( + RtpExtension::kDependencyDescriptorUri, + proto_header_extensions.dependency_descriptor_id()); + } return rtp_extensions; } // End of conversion functions. @@ -972,8 +1003,9 @@ ParsedRtcEventLog::GetDefaultHeaderExtensionMap() { constexpr int kPlayoutDelayDefaultId = 6; constexpr int kVideoContentTypeDefaultId = 7; constexpr int kVideoTimingDefaultId = 8; + constexpr int kDependencyDescriptorDefaultId = 9; - webrtc::RtpHeaderExtensionMap default_map; + webrtc::RtpHeaderExtensionMap default_map(/*extmap_allow_mixed=*/true); default_map.Register(kAudioLevelDefaultId); default_map.Register(kTimestampOffsetDefaultId); default_map.Register(kAbsSendTimeDefaultId); @@ -983,6 +1015,8 @@ ParsedRtcEventLog::GetDefaultHeaderExtensionMap() { default_map.Register(kPlayoutDelayDefaultId); default_map.Register(kVideoContentTypeDefaultId); default_map.Register(kVideoTimingDefaultId); + default_map.Register( + kDependencyDescriptorDefaultId); return default_map; } diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest.cc b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest.cc index 314bfd90e9769..3730a080ddcca 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest.cc +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest.cc @@ -45,6 +45,7 @@ #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h" #include "logging/rtc_event_log/rtc_stream_config.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "rtc_base/checks.h" #include "rtc_base/fake_clock.h" @@ -228,7 +229,9 @@ void RtcEventLogSession::WriteAudioRecvConfigs(size_t audio_recv_streams, do { ssrc = prng_.Rand(); } while (SsrcUsed(ssrc, incoming_extensions_)); - RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( + /*configure_all=*/false, + /*excluded_extensions=*/{RtpDependencyDescriptorExtension::kId}); incoming_extensions_.emplace_back(ssrc, extensions); auto event = gen_.NewAudioReceiveStreamConfig(ssrc, extensions); event_log->Log(event->Copy()); @@ -245,7 +248,9 @@ void RtcEventLogSession::WriteAudioSendConfigs(size_t audio_send_streams, do { ssrc = prng_.Rand(); } while (SsrcUsed(ssrc, outgoing_extensions_)); - RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( + /*configure_all=*/false, + /*excluded_extensions=*/{RtpDependencyDescriptorExtension::kId}); outgoing_extensions_.emplace_back(ssrc, extensions); auto event = gen_.NewAudioSendStreamConfig(ssrc, extensions); event_log->Log(event->Copy()); @@ -263,6 +268,10 @@ void RtcEventLogSession::WriteVideoRecvConfigs(size_t video_recv_streams, RtpHeaderExtensionMap all_extensions = ParsedRtcEventLog::GetDefaultHeaderExtensionMap(); + if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { + all_extensions.Deregister(RtpDependencyDescriptorExtension::Uri()); + } + clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); uint32_t ssrc = prng_.Rand(); incoming_extensions_.emplace_back(ssrc, all_extensions); @@ -274,7 +283,12 @@ void RtcEventLogSession::WriteVideoRecvConfigs(size_t video_recv_streams, do { ssrc = prng_.Rand(); } while (SsrcUsed(ssrc, incoming_extensions_)); - RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + std::vector excluded_extensions; + if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { + excluded_extensions.push_back(RtpDependencyDescriptorExtension::kId); + } + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( + /*configure_all=*/false, excluded_extensions); incoming_extensions_.emplace_back(ssrc, extensions); auto new_event = gen_.NewVideoReceiveStreamConfig(ssrc, extensions); event_log->Log(new_event->Copy()); @@ -292,6 +306,10 @@ void RtcEventLogSession::WriteVideoSendConfigs(size_t video_send_streams, RtpHeaderExtensionMap all_extensions = ParsedRtcEventLog::GetDefaultHeaderExtensionMap(); + if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { + all_extensions.Deregister(RtpDependencyDescriptorExtension::Uri()); + } + clock_.AdvanceTime(TimeDelta::Millis(prng_.Rand(20))); uint32_t ssrc = prng_.Rand(); outgoing_extensions_.emplace_back(ssrc, all_extensions); @@ -303,7 +321,12 @@ void RtcEventLogSession::WriteVideoSendConfigs(size_t video_send_streams, do { ssrc = prng_.Rand(); } while (SsrcUsed(ssrc, outgoing_extensions_)); - RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + std::vector excluded_extensions; + if (std::get<2>(GetParam()) == RtcEventLog::EncodingType::Legacy) { + excluded_extensions.push_back(RtpDependencyDescriptorExtension::kId); + } + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap( + /*configure_all=*/false, excluded_extensions); outgoing_extensions_.emplace_back(ssrc, extensions); auto event = gen_.NewVideoSendStreamConfig(ssrc, extensions); event_log->Log(event->Copy()); diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index 43b6fc81dcb1d..b378e8ff489ba 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -35,12 +35,14 @@ #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h" #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" +#include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #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/gtest.h" @@ -58,8 +60,8 @@ struct ExtensionPair { constexpr int kMaxCsrcs = 3; // Maximum serialized size of a header extension, including 1 byte ID. -constexpr int kMaxExtensionSizeBytes = 4; -constexpr int kMaxNumExtensions = 5; +constexpr int kMaxExtensionSizeBytes = 10; +constexpr int kMaxNumExtensions = 6; constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { {RTPExtensionType::kRtpExtensionTransmissionTimeOffset, @@ -70,7 +72,9 @@ constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { RtpExtension::kTransportSequenceNumberUri}, {RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri}, {RTPExtensionType::kRtpExtensionVideoRotation, - RtpExtension::kVideoRotationUri}}; + RtpExtension::kVideoRotationUri}, + {RTPExtensionType::kRtpExtensionDependencyDescriptor, + RtpExtension::kDependencyDescriptorUri}}; template void ShuffleInPlace(Random* prng, rtc::ArrayView array) { @@ -614,6 +618,15 @@ void EventGenerator::RandomizeRtpPacket( rtp_packet->SetExtension(prng_.Rand()); } + if (extension_map.IsRegistered(RtpDependencyDescriptorExtension::kId) && + (all_configured_exts || prng_.Rand())) { + std::vector raw_data(3 + prng_.Rand(6)); + for (uint8_t& d : raw_data) { + d = prng_.Rand(); + } + rtp_packet->SetRawExtension(raw_data); + } + RTC_CHECK_LE(rtp_packet->headers_size() + payload_size, IP_PACKET_SIZE); uint8_t* payload = rtp_packet->AllocatePayload(payload_size); @@ -675,8 +688,7 @@ std::unique_ptr EventGenerator::NewRtpPacketOutgoing( 1 - padding_size - kMaxHeaderSize)); - RtpPacketToSend rtp_packet(&extension_map, - kMaxHeaderSize + payload_size + padding_size); + RtpPacketToSend rtp_packet(&extension_map); RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, &rtp_packet, all_configured_exts); @@ -686,28 +698,41 @@ std::unique_ptr EventGenerator::NewRtpPacketOutgoing( } RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap( - bool configure_all) { + bool configure_all, + const std::vector& excluded_extensions) { RtpHeaderExtensionMap extension_map; std::vector id(RtpExtension::kOneByteHeaderExtensionMaxId - RtpExtension::kMinId + 1); std::iota(id.begin(), id.end(), RtpExtension::kMinId); ShuffleInPlace(&prng_, rtc::ArrayView(id)); - if (configure_all || prng_.Rand()) { + auto not_excluded = [&](RTPExtensionType type) -> bool { + return !absl::c_linear_search(excluded_extensions, type); + }; + + if (not_excluded(AudioLevel::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[0]); } - if (configure_all || prng_.Rand()) { + if (not_excluded(TransmissionOffset::kId) && + (configure_all || prng_.Rand())) { extension_map.Register(id[1]); } - if (configure_all || prng_.Rand()) { + if (not_excluded(AbsoluteSendTime::kId) && + (configure_all || prng_.Rand())) { extension_map.Register(id[2]); } - if (configure_all || prng_.Rand()) { + if (not_excluded(VideoOrientation::kId) && + (configure_all || prng_.Rand())) { extension_map.Register(id[3]); } - if (configure_all || prng_.Rand()) { + if (not_excluded(TransportSequenceNumber::kId) && + (configure_all || prng_.Rand())) { extension_map.Register(id[4]); } + if (not_excluded(RtpDependencyDescriptorExtension::kId) && + (configure_all || prng_.Rand())) { + extension_map.Register(id[5]); + } return extension_map; } @@ -1006,6 +1031,27 @@ 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 { + 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); + } +} + void EventVerifier::VerifyLoggedRouteChangeEvent( const RtcEventRouteChange& original_event, const LoggedRouteChangeEvent& logged_event) const { @@ -1039,6 +1085,8 @@ void EventVerifier::VerifyLoggedRtpPacketIncoming( logged_event.rtp.header.paddingLength); VerifyLoggedRtpHeader(original_event, logged_event.rtp.header); + VerifyLoggedDependencyDescriptor( + original_event, logged_event.rtp.dependency_descriptor_wire_format); } void EventVerifier::VerifyLoggedRtpPacketOutgoing( @@ -1059,6 +1107,8 @@ void EventVerifier::VerifyLoggedRtpPacketOutgoing( // someone has a strong reason to keep it, it'll be removed. VerifyLoggedRtpHeader(original_event, logged_event.rtp.header); + VerifyLoggedDependencyDescriptor( + original_event, logged_event.rtp.dependency_descriptor_wire_format); } void EventVerifier::VerifyLoggedGenericPacketSent( @@ -1122,8 +1172,8 @@ void EventVerifier::VerifyReportBlock( logged_report_block.source_ssrc()); EXPECT_EQ(original_report_block.fraction_lost(), logged_report_block.fraction_lost()); - EXPECT_EQ(original_report_block.cumulative_lost_signed(), - logged_report_block.cumulative_lost_signed()); + EXPECT_EQ(original_report_block.cumulative_lost(), + logged_report_block.cumulative_lost()); EXPECT_EQ(original_report_block.extended_high_seq_num(), logged_report_block.extended_high_seq_num()); EXPECT_EQ(original_report_block.jitter(), logged_report_block.jitter()); diff --git a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h index 7b863fd8a0625..950a622f8befb 100644 --- a/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h +++ b/third_party/libwebrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -15,6 +15,7 @@ #include #include +#include #include "logging/rtc_event_log/events/rtc_event_alr_state.h" #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" @@ -124,8 +125,11 @@ class EventGenerator { bool all_configured_exts = true); // `configure_all` determines whether all supported extensions are configured, - // or a random subset. - RtpHeaderExtensionMap NewRtpHeaderExtensionMap(bool configure_all = false); + // or a random subset. Extensions in `excluded_extensions` will always be + // excluded. + RtpHeaderExtensionMap NewRtpHeaderExtensionMap( + bool configure_all = false, + const std::vector& excluded_extensions = {}); std::unique_ptr NewAudioReceiveStreamConfig( uint32_t ssrc, diff --git a/third_party/libwebrtc/media/BUILD.gn b/third_party/libwebrtc/media/BUILD.gn index 3c4f757155c6c..a3d03da7357e7 100644 --- a/third_party/libwebrtc/media/BUILD.gn +++ b/third_party/libwebrtc/media/BUILD.gn @@ -828,9 +828,17 @@ if (rtc_include_tests) { "../api/video:video_codec_constants", "../api/video:video_frame", "../api/video:video_rtp_headers", - "../api/video_codecs:builtin_video_decoder_factory", - "../api/video_codecs:builtin_video_encoder_factory", "../api/video_codecs:video_codecs_api", + "../api/video_codecs:video_decoder_factory_template", + "../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../audio", "../call:call_interfaces", "../common_video", diff --git a/third_party/libwebrtc/media/base/fake_media_engine.cc b/third_party/libwebrtc/media/base/fake_media_engine.cc index b25288342a296..3e8a29b90e6bb 100644 --- a/third_party/libwebrtc/media/base/fake_media_engine.cc +++ b/third_party/libwebrtc/media/base/fake_media_engine.cc @@ -444,7 +444,7 @@ void FakeVideoMediaChannel::GenerateSendKeyFrame( FakeVoiceEngine::FakeVoiceEngine() : fail_create_channel_(false) { // Add a fake audio codec. Note that the name must not be "" as there are // sanity checks against that. - SetCodecs({AudioCodec(101, "fake_audio_codec", 0, 0, 1)}); + SetCodecs({AudioCodec(101, "fake_audio_codec", 8000, 0, 1)}); } void FakeVoiceEngine::Init() {} rtc::scoped_refptr FakeVoiceEngine::GetAudioState() const { @@ -544,8 +544,8 @@ FakeVideoEngine::FakeVideoEngine() : capture_(false), fail_create_channel_(false) { // Add a fake video codec. Note that the name must not be "" as there are // sanity checks against that. - send_codecs_.push_back(VideoCodec(0, "fake_video_codec")); - recv_codecs_.push_back(VideoCodec(0, "fake_video_codec")); + send_codecs_.push_back(VideoCodec(111, "fake_video_codec")); + recv_codecs_.push_back(VideoCodec(111, "fake_video_codec")); } bool FakeVideoEngine::SetOptions(const VideoOptions& options) { options_ = options; diff --git a/third_party/libwebrtc/media/base/media_channel.h b/third_party/libwebrtc/media/base/media_channel.h index ab4eb79508c34..3ce7327fea237 100644 --- a/third_party/libwebrtc/media/base/media_channel.h +++ b/third_party/libwebrtc/media/base/media_channel.h @@ -378,7 +378,7 @@ struct MediaSenderInfo { // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-retransmittedpacketssent uint64_t retransmitted_packets_sent = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-nackcount - uint32_t nacks_rcvd = 0; + uint32_t nacks_received = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-targetbitrate absl::optional target_bitrate; int packets_lost = 0; @@ -434,10 +434,10 @@ struct MediaReceiverInfo { } // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-bytesreceived - int64_t payload_bytes_rcvd = 0; + int64_t payload_bytes_received = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-headerbytesreceived - int64_t header_and_padding_bytes_rcvd = 0; - int packets_rcvd = 0; + int64_t header_and_padding_bytes_received = 0; + int packets_received = 0; int packets_lost = 0; absl::optional nacks_sent; // Jitter (network-related) latency (cumulative). @@ -560,8 +560,8 @@ struct VideoSenderInfo : public MediaSenderInfo { ~VideoSenderInfo(); std::vector ssrc_groups; std::string encoder_implementation_name; - int firs_rcvd = 0; - int plis_rcvd = 0; + int firs_received = 0; + int plis_received = 0; int send_frame_width = 0; int send_frame_height = 0; int frames = 0; @@ -610,7 +610,7 @@ struct VideoReceiverInfo : public MediaReceiverInfo { int plis_sent = 0; int frame_width = 0; int frame_height = 0; - int framerate_rcvd = 0; + int framerate_received = 0; int framerate_decoded = 0; int framerate_output = 0; // Framerate as sent to the renderer. diff --git a/third_party/libwebrtc/media/base/media_constants.cc b/third_party/libwebrtc/media/base/media_constants.cc index f91ac33c90228..911f510afef55 100644 --- a/third_party/libwebrtc/media/base/media_constants.cc +++ b/third_party/libwebrtc/media/base/media_constants.cc @@ -15,7 +15,7 @@ namespace cricket { const int kVideoCodecClockrate = 90000; const int kVideoMtu = 1200; -const int kVideoRtpSendBufferSize = 65536; +const int kVideoRtpSendBufferSize = 262144; const int kVideoRtpRecvBufferSize = 262144; const float kHighSystemCpuThreshold = 0.85f; diff --git a/third_party/libwebrtc/media/base/video_adapter.cc b/third_party/libwebrtc/media/base/video_adapter.cc index 149071d1534e2..01aaad13d33eb 100644 --- a/third_party/libwebrtc/media/base/video_adapter.cc +++ b/third_party/libwebrtc/media/base/video_adapter.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,8 @@ struct Fraction { // Determines number of output pixels if both width and height of an input of // `input_pixels` pixels is scaled with the fraction numerator / denominator. int scale_pixel_count(int input_pixels) { - return (numerator * numerator * input_pixels) / (denominator * denominator); + return (numerator * numerator * static_cast(input_pixels)) + / (denominator * denominator); } }; diff --git a/third_party/libwebrtc/media/base/video_adapter_unittest.cc b/third_party/libwebrtc/media/base/video_adapter_unittest.cc index 3a8d2e6098c20..778e61e74c65d 100644 --- a/third_party/libwebrtc/media/base/video_adapter_unittest.cc +++ b/third_party/libwebrtc/media/base/video_adapter_unittest.cc @@ -839,6 +839,16 @@ TEST_P(VideoAdapterTest, RequestAspectRatio) { EXPECT_EQ(360, cropped_height_); EXPECT_EQ(640, out_width_); EXPECT_EQ(360, out_height_); + + adapter_.OnOutputFormatRequest(std::make_pair(1280, 720), 1280 * 720 - 1, + absl::nullopt); + EXPECT_TRUE(adapter_.AdaptFrameResolution(2592, 1944, 0, &cropped_width_, + &cropped_height_, &out_width_, + &out_height_)); + EXPECT_EQ(2592, cropped_width_); + EXPECT_EQ(1458, cropped_height_); + EXPECT_EQ(1152, out_width_); + EXPECT_EQ(648, out_height_); } TEST_P(VideoAdapterTest, RequestAspectRatioWithDifferentOrientation) { diff --git a/third_party/libwebrtc/media/engine/webrtc_video_engine.cc b/third_party/libwebrtc/media/engine/webrtc_video_engine.cc index a8b58c07e3475..83581bf9fd2f4 100644 --- a/third_party/libwebrtc/media/engine/webrtc_video_engine.cc +++ b/third_party/libwebrtc/media/engine/webrtc_video_engine.cc @@ -695,8 +695,6 @@ WebRtcVideoChannel::WebRtcVideoChannel( "WebRTC-Video-DiscardPacketsWithUnknownSsrc")), crypto_options_(crypto_options) { RTC_DCHECK_RUN_ON(&thread_checker_); - network_thread_checker_.Detach(); - rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; sending_ = false; recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs( @@ -2788,9 +2786,9 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetPerLayerVideoSenderInfos( stream_stats.rtp_stats.retransmitted.payload_bytes; info.retransmitted_packets_sent = stream_stats.rtp_stats.retransmitted.packets; - info.firs_rcvd = stream_stats.rtcp_packet_type_counts.fir_packets; - info.nacks_rcvd = stream_stats.rtcp_packet_type_counts.nack_packets; - info.plis_rcvd = stream_stats.rtcp_packet_type_counts.pli_packets; + info.firs_received = stream_stats.rtcp_packet_type_counts.fir_packets; + info.nacks_received = stream_stats.rtcp_packet_type_counts.nack_packets; + info.plis_received = stream_stats.rtcp_packet_type_counts.pli_packets; if (stream_stats.report_block_data.has_value()) { info.packets_lost = stream_stats.report_block_data->report_block().packets_lost; @@ -2840,9 +2838,9 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetAggregatedVideoSenderInfo( info.send_frame_width = infos[i].send_frame_width; if (infos[i].send_frame_height > info.send_frame_height) info.send_frame_height = infos[i].send_frame_height; - info.firs_rcvd += infos[i].firs_rcvd; - info.nacks_rcvd += infos[i].nacks_rcvd; - info.plis_rcvd += infos[i].plis_rcvd; + info.firs_received += infos[i].firs_received; + info.nacks_received += infos[i].nacks_received; + info.plis_received += infos[i].plis_received; if (infos[i].report_block_datas.size()) info.report_block_datas.push_back(infos[i].report_block_datas[0]); if (infos[i].qp_sum) { @@ -3303,15 +3301,15 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo( if (decoder_it != config_.decoders.end()) info.codec_name = decoder_it->video_format.name; } - info.payload_bytes_rcvd = stats.rtp_stats.packet_counter.payload_bytes; - info.header_and_padding_bytes_rcvd = + info.payload_bytes_received = stats.rtp_stats.packet_counter.payload_bytes; + info.header_and_padding_bytes_received = stats.rtp_stats.packet_counter.header_bytes + stats.rtp_stats.packet_counter.padding_bytes; - info.packets_rcvd = stats.rtp_stats.packet_counter.packets; + info.packets_received = stats.rtp_stats.packet_counter.packets; info.packets_lost = stats.rtp_stats.packets_lost; info.jitter_ms = stats.rtp_stats.jitter / (kVideoCodecClockrate / 1000); - info.framerate_rcvd = stats.network_frame_rate; + info.framerate_received = stats.network_frame_rate; info.framerate_decoded = stats.decode_frame_rate; info.framerate_output = stats.render_frame_rate; info.frame_width = stats.width; diff --git a/third_party/libwebrtc/media/engine/webrtc_video_engine.h b/third_party/libwebrtc/media/engine/webrtc_video_engine.h index e6c9c28586cab..2cdd05ffd6db1 100644 --- a/third_party/libwebrtc/media/engine/webrtc_video_engine.h +++ b/third_party/libwebrtc/media/engine/webrtc_video_engine.h @@ -613,7 +613,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, webrtc::TaskQueueBase* const worker_thread_; webrtc::ScopedTaskSafety task_safety_; - RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_thread_checker_; + RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_thread_checker_{ + webrtc::SequenceChecker::kDetached}; RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_; uint32_t rtcp_receiver_report_ssrc_ RTC_GUARDED_BY(thread_checker_); diff --git a/third_party/libwebrtc/media/engine/webrtc_video_engine_unittest.cc b/third_party/libwebrtc/media/engine/webrtc_video_engine_unittest.cc index c86ceb61769fb..99d36b7a02139 100644 --- a/third_party/libwebrtc/media/engine/webrtc_video_engine_unittest.cc +++ b/third_party/libwebrtc/media/engine/webrtc_video_engine_unittest.cc @@ -36,13 +36,21 @@ #include "api/video/builtin_video_bitrate_allocator_factory.h" #include "api/video/i420_buffer.h" #include "api/video/video_bitrate_allocation.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/h264_profile_level_id.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "call/flexfec_receive_stream.h" #include "media/base/fake_frame_source.h" #include "media/base/fake_network_interface.h" @@ -95,6 +103,8 @@ using ::webrtc::RtpExtension; using ::webrtc::RtpPacket; using ::webrtc::RtpPacketReceived; using ::webrtc::ScalabilityMode; +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; using ::webrtc::test::RtcpPacketParser; namespace { @@ -102,12 +112,13 @@ static const int kDefaultQpMax = 56; static const uint8_t kRedRtxPayloadType = 125; -static const uint32_t kTimeout = 5000U; static const uint32_t kSsrc = 1234u; static const uint32_t kSsrcs4[] = {1, 2, 3, 4}; static const int kVideoWidth = 640; static const int kVideoHeight = 360; static const int kFramerate = 30; +static constexpr TimeDelta kFrameDuration = + TimeDelta::Millis(1000 / kFramerate); static const uint32_t kSsrcs1[] = {1}; static const uint32_t kSsrcs3[] = {1, 2, 3}; @@ -324,14 +335,15 @@ RtpPacketReceived BuildRtxPacket(uint32_t rtx_ssrc, } // namespace -#define EXPECT_FRAME_WAIT(c, w, h, t) \ - EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \ - EXPECT_EQ((w), renderer_.width()); \ +// TODO(tommi): Consider replacing these macros with custom matchers. +#define EXPECT_FRAME(c, w, h) \ + EXPECT_EQ((c), renderer_.num_rendered_frames()); \ + EXPECT_EQ((w), renderer_.width()); \ EXPECT_EQ((h), renderer_.height()); -#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \ - EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \ - EXPECT_EQ((w), (r).width()); \ +#define EXPECT_FRAME_ON_RENDERER(r, c, w, h) \ + EXPECT_EQ((c), (r).num_rendered_frames()); \ + EXPECT_EQ((w), (r).width()); \ EXPECT_EQ((h), (r).height()); namespace cricket { @@ -663,8 +675,7 @@ TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) { time_controller_.AdvanceTime(webrtc::TimeDelta::Zero()); // Sending one frame will have allocate the encoder. ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1)); - EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0, - kTimeout); + EXPECT_GT(encoder_factory_->encoders()[0]->GetNumEncodedFrames(), 0); int num_created_encoders = encoder_factory_->GetNumCreatedEncoders(); EXPECT_EQ(num_created_encoders, 1); @@ -1053,7 +1064,7 @@ TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) { frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame()); time_controller_.AdvanceTime(webrtc::TimeDelta::Zero()); - ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout); + ASSERT_EQ(1u, encoder_factory_->encoders().size()); cricket::VideoSendParameters new_parameters; new_parameters.codecs.push_back(GetEngineCodec("VP8")); @@ -1063,7 +1074,7 @@ TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) { frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame()); time_controller_.AdvanceTime(webrtc::TimeDelta::Zero()); - EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout); + EXPECT_EQ(1u, encoder_factory_->encoders().size()); } TEST_F(WebRtcVideoEngineTest, @@ -1587,13 +1598,17 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { } WebRtcVideoChannelEncodedFrameCallbackTest() - : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()), + : task_queue_factory_(time_controller_.CreateTaskQueueFactory()), call_(absl::WrapUnique(webrtc::Call::Create( GetCallConfig(&event_log_, task_queue_factory_.get())))), video_bitrate_allocator_factory_( webrtc::CreateBuiltinVideoBitrateAllocatorFactory()), engine_( - webrtc::CreateBuiltinVideoEncoderFactory(), + std::make_unique>(), std::make_unique( []() { return std::make_unique(); }, kSdpVideoFormats), @@ -1627,11 +1642,13 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test { void DeliverKeyFrameAndWait(uint32_t ssrc) { DeliverKeyFrame(ssrc); - EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_EQ(renderer_.num_rendered_frames(), 1); } static const std::vector kSdpVideoFormats; - rtc::AutoThread main_thread_; + webrtc::GlobalSimulatedTimeController time_controller_{ + Timestamp::Seconds(1000)}; webrtc::test::ScopedKeyValueConfig field_trials_; webrtc::RtcEventLogNull event_log_; std::unique_ptr task_queue_factory_; @@ -1660,7 +1677,8 @@ TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest, callback.AsStdFunction()); EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_)); DeliverKeyFrame(kSsrc); - EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_EQ(renderer_.num_rendered_frames(), 1); receive_channel_->RemoveRecvStream(kSsrc); } @@ -1673,7 +1691,8 @@ TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest, EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_)); channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction()); DeliverKeyFrame(kSsrc); - EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_EQ(renderer_.num_rendered_frames(), 1); receive_channel_->RemoveRecvStream(kSsrc); } @@ -1686,7 +1705,8 @@ TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest, EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_)); channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction()); DeliverKeyFrame(kSsrc); - EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_EQ(renderer_.num_rendered_frames(), 1); receive_channel_->RemoveRecvStream(kSsrc); } @@ -1724,11 +1744,19 @@ TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest, class WebRtcVideoChannelBaseTest : public ::testing::Test { protected: WebRtcVideoChannelBaseTest() - : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()), + : task_queue_factory_(time_controller_.CreateTaskQueueFactory()), video_bitrate_allocator_factory_( webrtc::CreateBuiltinVideoBitrateAllocatorFactory()), - engine_(webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), + engine_(std::make_unique>(), + std::make_unique>(), field_trials_) {} void SetUp() override { @@ -1739,6 +1767,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { call_config.trials = &field_trials_; call_.reset(webrtc::Call::Create(call_config)); } + cricket::MediaConfig media_config; // Disabling cpu overuse detection actually disables quality scaling too; it // implies DegradationPreference kMaintainResolution. Automatic scaling @@ -1831,11 +1860,12 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame()); } frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame()); + time_controller_.AdvanceTime(kFrameDuration); } bool WaitAndSendFrame(int wait_ms) { - bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms); + time_controller_.AdvanceTime(TimeDelta::Millis(wait_ms)); SendFrame(); - return ret; + return true; } int NumRtpBytes() { return network_interface_.NumRtpBytes(); } int NumRtpBytes(uint32_t ssrc) { @@ -1862,7 +1892,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0))); } @@ -1876,7 +1906,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { for (int i = 0; i < duration_sec; ++i) { for (int frame = 1; frame <= fps; ++frame) { EXPECT_TRUE(WaitAndSendFrame(1000 / fps)); - EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(frame + i * fps, kVideoWidth, kVideoHeight); } } EXPECT_EQ(codec.id, GetPayloadType(GetRtpPacket(0))); @@ -1902,9 +1932,8 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { // Test sending and receiving on first stream. SendAndReceive(codec); // Test sending and receiving on second stream. - EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout); + EXPECT_EQ(renderer2_.num_rendered_frames(), 1); EXPECT_GT(NumRtpPackets(), 0); - EXPECT_EQ(1, renderer2_.num_rendered_frames()); } cricket::VideoCodec GetEngineCodec(const std::string& name) { @@ -1923,7 +1952,9 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test { return cricket::StreamParams::CreateLegacy(kSsrc); } - rtc::AutoThread main_thread_; + webrtc::GlobalSimulatedTimeController time_controller_{ + Timestamp::Seconds(1000)}; + webrtc::RtcEventLogNull event_log_; webrtc::test::ScopedKeyValueConfig field_trials_; std::unique_ptr override_field_trials_; @@ -1956,7 +1987,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSend) { EXPECT_TRUE(SetSend(true)); EXPECT_TRUE(channel_->sending()); SendFrame(); - EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); + EXPECT_GT(NumRtpPackets(), 0); EXPECT_TRUE(SetSend(false)); EXPECT_FALSE(channel_->sending()); } @@ -1989,17 +2020,17 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStats) { EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); ASSERT_EQ(1U, send_info.senders.size()); - // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload? - // For webrtc, bytes_sent does not include the RTP header length. + // TODO(whyuan): bytes_sent and bytes_received are different. Are both + // payload? For webrtc, bytes_sent does not include the RTP header length. EXPECT_EQ(send_info.senders[0].payload_bytes_sent, NumRtpBytes() - kRtpHeaderSize * NumRtpPackets()); EXPECT_EQ(NumRtpPackets(), send_info.senders[0].packets_sent); EXPECT_EQ(0.0, send_info.senders[0].fraction_lost); ASSERT_TRUE(send_info.senders[0].codec_payload_type); EXPECT_EQ(DefaultCodec().id, *send_info.senders[0].codec_payload_type); - EXPECT_EQ(0, send_info.senders[0].firs_rcvd); - EXPECT_EQ(0, send_info.senders[0].plis_rcvd); - EXPECT_EQ(0u, send_info.senders[0].nacks_rcvd); + EXPECT_EQ(0, send_info.senders[0].firs_received); + EXPECT_EQ(0, send_info.senders[0].plis_received); + EXPECT_EQ(0u, send_info.senders[0].nacks_received); EXPECT_EQ(kVideoWidth, send_info.senders[0].send_frame_width); EXPECT_EQ(kVideoHeight, send_info.senders[0].send_frame_height); EXPECT_GT(send_info.senders[0].framerate_input, 0); @@ -2017,8 +2048,8 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStats) { ASSERT_TRUE(receive_info.receivers[0].codec_payload_type); EXPECT_EQ(DefaultCodec().id, *receive_info.receivers[0].codec_payload_type); EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), - receive_info.receivers[0].payload_bytes_rcvd); - EXPECT_EQ(NumRtpPackets(), receive_info.receivers[0].packets_rcvd); + receive_info.receivers[0].payload_bytes_received); + EXPECT_EQ(NumRtpPackets(), receive_info.receivers[0].packets_received); EXPECT_EQ(0, receive_info.receivers[0].packets_lost); // TODO(asapersson): Not set for webrtc. Handle missing stats. // EXPECT_EQ(0, receive_info.receivers[0].packets_concealed); @@ -2027,7 +2058,7 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStats) { EXPECT_EQ(0U, receive_info.receivers[0].nacks_sent); EXPECT_EQ(kVideoWidth, receive_info.receivers[0].frame_width); EXPECT_EQ(kVideoHeight, receive_info.receivers[0].frame_height); - EXPECT_GT(receive_info.receivers[0].framerate_rcvd, 0); + EXPECT_GT(receive_info.receivers[0].framerate_received, 0); EXPECT_GT(receive_info.receivers[0].framerate_decoded, 0); EXPECT_GT(receive_info.receivers[0].framerate_output, 0); @@ -2058,10 +2089,8 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { ssrcs.push_back(2); network_interface_.SetConferenceMode(true, ssrcs); SendFrame(); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight, - kTimeout); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight, - kTimeout); + EXPECT_FRAME_ON_RENDERER(renderer1, 1, kVideoWidth, kVideoHeight); + EXPECT_FRAME_ON_RENDERER(renderer2, 1, kVideoWidth, kVideoHeight); EXPECT_TRUE(channel_->SetSend(false)); @@ -2071,11 +2100,11 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); ASSERT_EQ(1U, send_info.senders.size()); - // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload? - // For webrtc, bytes_sent does not include the RTP header length. - EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), - GetSenderStats(0).payload_bytes_sent, kTimeout); - EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout); + // TODO(whyuan): bytes_sent and bytes_received are different. Are both + // payload? For webrtc, bytes_sent does not include the RTP header length. + EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), + GetSenderStats(0).payload_bytes_sent); + EXPECT_EQ(NumRtpPackets(), GetSenderStats(0).packets_sent); EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width); EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height); @@ -2083,11 +2112,11 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) { for (size_t i = 0; i < receive_info.receivers.size(); ++i) { EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size()); EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]); - EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), - GetReceiverStats(i).payload_bytes_rcvd, kTimeout); - EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout); - EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout); - EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout); + EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(), + GetReceiverStats(i).payload_bytes_received); + EXPECT_EQ(NumRtpPackets(), GetReceiverStats(i).packets_received); + EXPECT_EQ(kVideoWidth, GetReceiverStats(i).frame_width); + EXPECT_EQ(kVideoHeight, GetReceiverStats(i).frame_height); } } @@ -2105,8 +2134,8 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) { EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_)); EXPECT_TRUE(SetSend(true)); SendFrame(); - EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_GT(NumRtpPackets(), 0); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); // Add an additional capturer, and hook up a renderer to receive it. cricket::FakeVideoRenderer renderer2; @@ -2122,28 +2151,17 @@ TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) { cricket::StreamParams::CreateLegacy(5678))); EXPECT_TRUE(channel_->SetSink(5678, &renderer2)); frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame()); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight, - kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_FRAME_ON_RENDERER(renderer2, 1, kTestWidth, kTestHeight); - // Get stats, and make sure they are correct for two senders. We wait until - // the number of expected packets have been sent to avoid races where we - // check stats before it has been updated. + // Get stats, and make sure they are correct for two senders cricket::VideoMediaSendInfo send_info; - for (uint32_t i = 0; i < kTimeout; ++i) { - rtc::Thread::Current()->ProcessMessages(1); - EXPECT_TRUE(channel_->GetSendStats(&send_info)); + EXPECT_TRUE(channel_->GetSendStats(&send_info)); + + ASSERT_EQ(2U, send_info.senders.size()); - ASSERT_EQ(2U, send_info.senders.size()); - if (send_info.senders[0].packets_sent + send_info.senders[1].packets_sent == - NumRtpPackets()) { - // Stats have been updated for both sent frames, expectations can be - // checked now. - break; - } - } EXPECT_EQ(NumRtpPackets(), send_info.senders[0].packets_sent + - send_info.senders[1].packets_sent) - << "Timed out while waiting for packet counts for all sent packets."; + send_info.senders[1].packets_sent); EXPECT_EQ(1U, send_info.senders[0].ssrcs().size()); EXPECT_EQ(1234U, send_info.senders[0].ssrcs()[0]); EXPECT_EQ(kVideoWidth, send_info.senders[0].send_frame_width); @@ -2171,15 +2189,15 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) { EXPECT_TRUE(SetDefaultCodec()); EXPECT_TRUE(SetSend(true)); SendFrame(); - EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); + EXPECT_GT(NumRtpPackets(), 0); RtpPacket header; EXPECT_TRUE(header.Parse(GetRtpPacket(0))); EXPECT_EQ(kSsrc, header.Ssrc()); // Packets are being paced out, so these can mismatch between the first and // second call to NumRtpPackets until pending packets are paced out. - EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout); - EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout); + EXPECT_EQ(NumRtpPackets(), NumRtpPackets(header.Ssrc())); + EXPECT_EQ(NumRtpBytes(), NumRtpBytes(header.Ssrc())); EXPECT_EQ(1, NumSentSsrcs()); EXPECT_EQ(0, NumRtpPackets(kSsrc - 1)); EXPECT_EQ(0, NumRtpBytes(kSsrc - 1)); @@ -2195,14 +2213,14 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) { EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get())); EXPECT_TRUE(SetSend(true)); EXPECT_TRUE(WaitAndSendFrame(0)); - EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout); + EXPECT_GT(NumRtpPackets(), 0); RtpPacket header; EXPECT_TRUE(header.Parse(GetRtpPacket(0))); EXPECT_EQ(999u, header.Ssrc()); // Packets are being paced out, so these can mismatch between the first and // second call to NumRtpPackets until pending packets are paced out. - EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.Ssrc()), kTimeout); - EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.Ssrc()), kTimeout); + EXPECT_EQ(NumRtpPackets(), NumRtpPackets(header.Ssrc())); + EXPECT_EQ(NumRtpBytes(), NumRtpBytes(header.Ssrc())); EXPECT_EQ(1, NumSentSsrcs()); EXPECT_EQ(0, NumRtpPackets(kSsrc)); EXPECT_EQ(0, NumRtpBytes(kSsrc)); @@ -2220,7 +2238,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SetSink) { channel_->SetDefaultSink(&renderer_); channel_->OnPacketReceived(packet); SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); } // Tests setting up and configuring a send stream. @@ -2229,7 +2247,7 @@ TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) { EXPECT_TRUE(SetSend(true)); channel_->SetDefaultSink(&renderer_); SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); EXPECT_GT(NumRtpPackets(), 0); RtpPacket header; size_t last_packet = NumRtpPackets() - 1; @@ -2246,7 +2264,7 @@ TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) { EXPECT_EQ(rtp_packets, NumRtpPackets()); // Wait 30ms to guarantee the engine does not drop the frame. EXPECT_TRUE(WaitAndSendFrame(30)); - EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout); + EXPECT_GT(NumRtpPackets(), rtp_packets); last_packet = NumRtpPackets() - 1; EXPECT_TRUE(header.Parse(GetRtpPacket(static_cast(last_packet)))); @@ -2275,10 +2293,8 @@ TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) { ssrcs.push_back(2); network_interface_.SetConferenceMode(true, ssrcs); SendFrame(); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight, - kTimeout); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight, - kTimeout); + EXPECT_FRAME_ON_RENDERER(renderer1, 1, kVideoWidth, kVideoHeight); + EXPECT_FRAME_ON_RENDERER(renderer2, 1, kVideoWidth, kVideoHeight); EXPECT_EQ(DefaultCodec().id, GetPayloadType(GetRtpPacket(0))); EXPECT_EQ(kVideoWidth, renderer1.width()); @@ -2303,7 +2319,7 @@ TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) { channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); webrtc::test::FrameForwarder frame_forwarder; cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30, @@ -2319,28 +2335,26 @@ TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) { int captured_frames = 1; for (int iterations = 0; iterations < 2; ++iterations) { EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder)); - rtc::Thread::Current()->ProcessMessages(time_between_send_ms); + time_controller_.AdvanceTime(TimeDelta::Millis(time_between_send_ms)); frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame()); ++captured_frames; - // Wait until frame of right size is captured. - EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames && - 480 == renderer_.width() && - 360 == renderer_.height() && !renderer_.black_frame(), - kTimeout); + // Check if the right size was captured. + EXPECT_TRUE(renderer_.num_rendered_frames() >= captured_frames && + 480 == renderer_.width() && 360 == renderer_.height() && + !renderer_.black_frame()); EXPECT_GE(renderer_.num_rendered_frames(), captured_frames); EXPECT_EQ(480, renderer_.width()); EXPECT_EQ(360, renderer_.height()); captured_frames = renderer_.num_rendered_frames() + 1; EXPECT_FALSE(renderer_.black_frame()); EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr)); - // Make sure a black frame is generated within the specified timeout. - // The black frame should be the resolution of the previous frame to + // Make sure a black frame was generated. + // The black frame should have the resolution of the previous frame to // prevent expensive encoder reconfigurations. - EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames && - 480 == renderer_.width() && - 360 == renderer_.height() && renderer_.black_frame(), - kTimeout); + EXPECT_TRUE(renderer_.num_rendered_frames() >= captured_frames && + 480 == renderer_.width() && 360 == renderer_.height() && + renderer_.black_frame()); EXPECT_GE(renderer_.num_rendered_frames(), captured_frames); EXPECT_EQ(480, renderer_.width()); EXPECT_EQ(360, renderer_.height()); @@ -2363,26 +2377,22 @@ TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) { channel_->SetDefaultSink(&renderer_); EXPECT_EQ(0, renderer_.num_rendered_frames()); SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); - // Wait for one frame so they don't get dropped because we send frames too + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); + // Allow one frame so they don't get dropped because we send frames too // tightly. - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); // Remove the capturer. EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr)); // No capturer was added, so this SetVideoSend shouldn't do anything. EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr)); - rtc::Thread::Current()->ProcessMessages(300); + time_controller_.AdvanceTime(TimeDelta::Millis(300)); // Verify no more frames were sent. EXPECT_EQ(1, renderer_.num_rendered_frames()); } // Tests that we can add and remove capturer as unique sources. TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) { - // WebRTC implementation will drop frames if pushed to quickly. Wait the - // interval time to avoid that. - // WebRTC implementation will drop frames if pushed to quickly. Wait the - // interval time to avoid that. // Set up the stream associated with the engine. EXPECT_TRUE(receive_channel_->AddRecvStream( cricket::StreamParams::CreateLegacy(kSsrc))); @@ -2427,14 +2437,14 @@ TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) { frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame( kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0, rtc::kNumMicrosecsPerSec / kFramerate)); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight, - kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_FRAME_ON_RENDERER(renderer1, 1, kTestWidth, kTestHeight); // Capture a frame with additional capturer2, frames should be received frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame( kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0, rtc::kNumMicrosecsPerSec / kFramerate)); - EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight, - kTimeout); + time_controller_.AdvanceTime(kFrameDuration); + EXPECT_FRAME_ON_RENDERER(renderer2, 1, kTestWidth, kTestHeight); // Successfully remove the capturer. EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr)); // The capturers must be unregistered here as it runs out of it's scope @@ -2509,13 +2519,13 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) { // RequestEncoderFallback will post a task to the worker thread (which is also // the current thread), hence the ProcessMessages call. channel_->RequestEncoderFallback(); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); ASSERT_TRUE(channel_->GetSendCodec(&codec)); EXPECT_EQ("VP8", codec.name); // No other codec to fall back to, keep using VP8. channel_->RequestEncoderFallback(); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); ASSERT_TRUE(channel_->GetSendCodec(&codec)); EXPECT_EQ("VP8", codec.name); } @@ -2534,7 +2544,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) { // the current thread), hence the ProcessMessages call. channel_->RequestEncoderSwitch(webrtc::SdpVideoFormat("UnavailableCodec"), /*allow_default_fallback=*/true); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); // Requested encoder is not available. Default fallback is allowed. Switch to // the next negotiated codec, VP8. @@ -2558,7 +2568,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) { channel_->RequestEncoderSwitch( webrtc::SdpVideoFormat("VP9", {{"profile-id", "1"}}), /*allow_default_fallback=*/false); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); // VP9 profile_id=1 is not available. Default fallback is not allowed. Switch // is not performed. @@ -2568,7 +2578,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) { channel_->RequestEncoderSwitch( webrtc::SdpVideoFormat("VP9", {{"profile-id", "0"}}), /*allow_default_fallback=*/false); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); // VP9 profile_id=0 is available. Switch encoder. ASSERT_TRUE(channel_->GetSendCodec(&codec)); @@ -2589,7 +2599,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SendCodecIsMovedToFrontInRtpParameters) { // RequestEncoderFallback will post a task to the worker thread (which is also // the current thread), hence the ProcessMessages call. channel_->RequestEncoderFallback(); - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); send_codecs = send_channel_->GetRtpSendParameters(kSsrc).codecs; ASSERT_EQ(send_codecs.size(), 2u); @@ -2655,7 +2665,6 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest { // the unsignalled receive stream cooldown is no longer in effect. void ReceivePacketAndAdvanceTime(const RtpPacketReceived& packet) { receive_channel_->OnPacketReceived(packet); - rtc::Thread::Current()->ProcessMessages(0); time_controller_.AdvanceTime( webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs)); } @@ -3232,7 +3241,7 @@ TEST_F(WebRtcVideoChannelTest, OnPacketReceivedIdentifiesExtensions) { ASSERT_TRUE(received_packet.Parse(reference_packet.Buffer())); receive_channel_->OnPacketReceived(received_packet); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); EXPECT_EQ(fake_call_->last_received_rtp_packet() .GetExtension(), @@ -5784,9 +5793,9 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportWithoutSubStreams) { EXPECT_EQ(sender.encoder_implementation_name, stats.encoder_implementation_name); // Comes from substream only. - EXPECT_EQ(sender.firs_rcvd, 0); - EXPECT_EQ(sender.plis_rcvd, 0); - EXPECT_EQ(sender.nacks_rcvd, 0u); + EXPECT_EQ(sender.firs_received, 0); + EXPECT_EQ(sender.plis_received, 0); + EXPECT_EQ(sender.nacks_received, 0u); EXPECT_EQ(sender.send_frame_width, 0); EXPECT_EQ(sender.send_frame_height, 0); @@ -5847,12 +5856,12 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { substream.rtcp_packet_type_counts.fir_packets = 14; substream.rtcp_packet_type_counts.nack_packets = 15; substream.rtcp_packet_type_counts.pli_packets = 16; - webrtc::RTCPReportBlock report_block; - report_block.packets_lost = 17; - report_block.fraction_lost = 18; + webrtc::rtcp::ReportBlock report_block; + report_block.SetCumulativeLost(17); + report_block.SetFractionLost(18); webrtc::ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, 0); - report_block_data.AddRoundTripTimeSample(19); + report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero()); + report_block_data.AddRoundTripTimeSample(webrtc::TimeDelta::Millis(19)); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; substream.frames_encoded = 21; @@ -5911,12 +5920,12 @@ TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) { EXPECT_EQ(sender.encoder_implementation_name, stats.encoder_implementation_name); EXPECT_EQ( - sender.firs_rcvd, + sender.firs_received, static_cast(2 * substream.rtcp_packet_type_counts.fir_packets)); EXPECT_EQ( - sender.plis_rcvd, + sender.plis_received, static_cast(2 * substream.rtcp_packet_type_counts.pli_packets)); - EXPECT_EQ(sender.nacks_rcvd, + EXPECT_EQ(sender.nacks_received, 2 * substream.rtcp_packet_type_counts.nack_packets); EXPECT_EQ(sender.send_frame_width, substream.width); EXPECT_EQ(sender.send_frame_height, substream.height); @@ -5973,12 +5982,12 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { substream.rtcp_packet_type_counts.fir_packets = 14; substream.rtcp_packet_type_counts.nack_packets = 15; substream.rtcp_packet_type_counts.pli_packets = 16; - webrtc::RTCPReportBlock report_block; - report_block.packets_lost = 17; - report_block.fraction_lost = 18; + webrtc::rtcp::ReportBlock report_block; + report_block.SetCumulativeLost(17); + report_block.SetFractionLost(18); webrtc::ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, 0); - report_block_data.AddRoundTripTimeSample(19); + report_block_data.SetReportBlock(0, report_block, webrtc::Timestamp::Zero()); + report_block_data.AddRoundTripTimeSample(webrtc::TimeDelta::Millis(19)); substream.report_block_data = report_block_data; substream.encode_frame_rate = 20.0; substream.frames_encoded = 21; @@ -6036,11 +6045,12 @@ TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) { EXPECT_EQ(sender.ssrc_groups.size(), 0u); EXPECT_EQ(sender.encoder_implementation_name, stats.encoder_implementation_name); - EXPECT_EQ(sender.firs_rcvd, + EXPECT_EQ(sender.firs_received, static_cast(substream.rtcp_packet_type_counts.fir_packets)); - EXPECT_EQ(sender.plis_rcvd, + EXPECT_EQ(sender.plis_received, static_cast(substream.rtcp_packet_type_counts.pli_packets)); - EXPECT_EQ(sender.nacks_rcvd, substream.rtcp_packet_type_counts.nack_packets); + EXPECT_EQ(sender.nacks_received, + substream.rtcp_packet_type_counts.nack_packets); EXPECT_EQ(sender.send_frame_width, substream.width); EXPECT_EQ(sender.send_frame_height, substream.height); @@ -6477,17 +6487,17 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) { EXPECT_TRUE(channel_->GetSendStats(&send_info)); EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - EXPECT_EQ(2, send_info.senders[0].firs_rcvd); - EXPECT_EQ(3u, send_info.senders[0].nacks_rcvd); - EXPECT_EQ(4, send_info.senders[0].plis_rcvd); + EXPECT_EQ(2, send_info.senders[0].firs_received); + EXPECT_EQ(3u, send_info.senders[0].nacks_received); + EXPECT_EQ(4, send_info.senders[0].plis_received); - EXPECT_EQ(5, send_info.senders[1].firs_rcvd); - EXPECT_EQ(7u, send_info.senders[1].nacks_rcvd); - EXPECT_EQ(9, send_info.senders[1].plis_rcvd); + EXPECT_EQ(5, send_info.senders[1].firs_received); + EXPECT_EQ(7u, send_info.senders[1].nacks_received); + EXPECT_EQ(9, send_info.senders[1].plis_received); - EXPECT_EQ(7, send_info.aggregated_senders[0].firs_rcvd); - EXPECT_EQ(10u, send_info.aggregated_senders[0].nacks_rcvd); - EXPECT_EQ(13, send_info.aggregated_senders[0].plis_rcvd); + EXPECT_EQ(7, send_info.aggregated_senders[0].firs_received); + EXPECT_EQ(10u, send_info.aggregated_senders[0].nacks_received); + EXPECT_EQ(13, send_info.aggregated_senders[0].plis_received); } TEST_F(WebRtcVideoChannelTest, @@ -6612,12 +6622,12 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) { EXPECT_TRUE(channel_->GetSendStats(&send_info)); EXPECT_TRUE(channel_->GetReceiveStats(&receive_info)); - EXPECT_EQ( - stats.rtp_stats.packet_counter.payload_bytes, - rtc::checked_cast(receive_info.receivers[0].payload_bytes_rcvd)); - EXPECT_EQ( - stats.rtp_stats.packet_counter.packets, - rtc::checked_cast(receive_info.receivers[0].packets_rcvd)); + EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes, + rtc::checked_cast( + receive_info.receivers[0].payload_bytes_received)); + EXPECT_EQ(stats.rtp_stats.packet_counter.packets, + rtc::checked_cast( + receive_info.receivers[0].packets_received)); EXPECT_EQ(stats.rtp_stats.packets_lost, receive_info.receivers[0].packets_lost); } @@ -6853,7 +6863,7 @@ TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) { ASSERT_TRUE(receive_channel_->AddRecvStream(unsignaled_stream)); receive_channel_->OnDemuxerCriteriaUpdatePending(); receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // The stream shouldn't have been created at this point because it doesn't // have any SSRCs. EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size()); @@ -6927,7 +6937,7 @@ TEST_F(WebRtcVideoChannelTest, receive_channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc1))); receive_channel_->OnDemuxerCriteriaUpdatePending(); receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); // If this is the only m= section the demuxer might be configure to forward @@ -6964,7 +6974,7 @@ TEST_F(WebRtcVideoChannelTest, // pending demuxer updates, receiving unknown ssrcs (kSsrc2) should again // result in unsignalled receive streams being created. receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Receive packets for kSsrc1 and kSsrc2 again. { @@ -6999,7 +7009,7 @@ TEST_F(WebRtcVideoChannelTest, receive_channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc2))); receive_channel_->OnDemuxerCriteriaUpdatePending(); receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); EXPECT_EQ(fake_call_->GetVideoReceiveStreams().size(), 2u); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc1), 0u); EXPECT_EQ(fake_call_->GetDeliveredPacketsForSsrc(kSsrc2), 0u); @@ -7036,7 +7046,7 @@ TEST_F(WebRtcVideoChannelTest, // Signal that the demuxer update is complete. This means we should stop // ignorning kSsrc1. receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Receive packets for kSsrc1 and kSsrc2 again. { @@ -7067,7 +7077,7 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { receive_channel_->AddRecvStream(StreamParams::CreateLegacy(kSsrc))); receive_channel_->OnDemuxerCriteriaUpdatePending(); receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); ASSERT_EQ(fake_call_->GetVideoReceiveStreams().size(), 1u); // Remove kSsrc... @@ -7092,7 +7102,7 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { // Signal that the demuxer knows about the first update: the removal. receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // This still should not prevent in-flight packets from arriving because we // have a receive stream for it. @@ -7120,7 +7130,7 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { // Signal that the demuxer knows about the second update: adding it back. receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // The packets should continue to be dropped because removal happened after // the most recently completed demuxer update. @@ -7134,7 +7144,7 @@ TEST_F(WebRtcVideoChannelTest, MultiplePendingDemuxerCriteriaUpdates) { // Signal that the demuxer knows about the last update: the second removal. receive_channel_->OnDemuxerCriteriaUpdateComplete(); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // If packets still arrive after the demuxer knows about the latest removal we // should finally create an unsignalled receive stream. @@ -7158,7 +7168,7 @@ TEST_F(WebRtcVideoChannelTest, UnsignalledSsrcHasACooldown) { packet.SetSsrc(kSsrc1); receive_channel_->OnPacketReceived(packet); } - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime( webrtc::TimeDelta::Millis(kUnsignalledReceiveStreamCooldownMs - 1)); @@ -7173,7 +7183,7 @@ TEST_F(WebRtcVideoChannelTest, UnsignalledSsrcHasACooldown) { packet.SetSsrc(kSsrc2); receive_channel_->OnPacketReceived(packet); } - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Not enough time has passed to replace the unsignalled receive stream, so // the kSsrc2 should be ignored. @@ -7190,7 +7200,7 @@ TEST_F(WebRtcVideoChannelTest, UnsignalledSsrcHasACooldown) { packet.SetSsrc(kSsrc2); receive_channel_->OnPacketReceived(packet); } - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); // The old unsignalled receive stream was destroyed and replaced, so we still // only have one unsignalled receive stream. But tha packet counter for kSsrc2 @@ -7374,7 +7384,7 @@ TEST_F(WebRtcVideoChannelTest, rtx_packet.SetPayloadType(rtx_vp8_payload_type); rtx_packet.SetSsrc(rtx_ssrc); receive_channel_->OnPacketReceived(rtx_packet); - rtc::Thread::Current()->ProcessMessages(0); + time_controller_.AdvanceTime(TimeDelta::Zero()); EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size()); // Send media packet. @@ -9630,7 +9640,7 @@ TEST_F(WebRtcVideoChannelBaseTest, GetSources) { // Send and receive one frame. SendFrame(); - EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(1, kVideoWidth, kVideoHeight); EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty()); EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1)); @@ -9644,7 +9654,7 @@ TEST_F(WebRtcVideoChannelBaseTest, GetSources) { // Send and receive another frame. SendFrame(); - EXPECT_FRAME_WAIT(2, kVideoWidth, kVideoHeight, kTimeout); + EXPECT_FRAME(2, kVideoWidth, kVideoHeight); EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty()); EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1)); @@ -9697,8 +9707,7 @@ TEST_F(WebRtcVideoChannelBaseTest, EncoderSelectorSwitchCodec) { .WillRepeatedly(Return(webrtc::SdpVideoFormat("VP9"))); channel_->SetEncoderSelector(kSsrc, &encoder_selector); - - rtc::Thread::Current()->ProcessMessages(30); + time_controller_.AdvanceTime(kFrameDuration); ASSERT_TRUE(channel_->GetSendCodec(&codec)); EXPECT_EQ("VP9", codec.name); diff --git a/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc b/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc index ab9a3fc7b80dc..55cebbaa546b1 100644 --- a/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc +++ b/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc @@ -305,9 +305,6 @@ WebRtcVoiceEngine::WebRtcVoiceEngine( audio_frame_processor_(audio_frame_processor), minimized_remsampling_on_mobile_trial_enabled_( IsEnabled(trials, "WebRTC-Audio-MinimizeResamplingOnMobile")) { - // This may be called from any thread, so detach thread checkers. - worker_thread_checker_.Detach(); - signal_thread_checker_.Detach(); RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; RTC_DCHECK(decoder_factory); RTC_DCHECK(encoder_factory); @@ -1265,7 +1262,6 @@ WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel( audio_config_(config.audio), codec_pair_id_(codec_pair_id), crypto_options_(crypto_options) { - network_thread_checker_.Detach(); RTC_LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; RTC_DCHECK(call); SetOptions(options); @@ -2335,7 +2331,7 @@ bool WebRtcVoiceMediaChannel::GetSendStats(VoiceMediaSendInfo* info) { sinfo.retransmitted_packets_sent = stats.retransmitted_packets_sent; sinfo.packets_lost = stats.packets_lost; sinfo.fraction_lost = stats.fraction_lost; - sinfo.nacks_rcvd = stats.nacks_rcvd; + sinfo.nacks_received = stats.nacks_received; sinfo.target_bitrate = stats.target_bitrate_bps; sinfo.codec_name = stats.codec_name; sinfo.codec_payload_type = stats.codec_payload_type; @@ -2391,9 +2387,10 @@ bool WebRtcVoiceMediaChannel::GetReceiveStats(VoiceMediaReceiveInfo* info, stream.second->GetStats(get_and_clear_legacy_stats); VoiceReceiverInfo rinfo; rinfo.add_ssrc(stats.remote_ssrc); - rinfo.payload_bytes_rcvd = stats.payload_bytes_rcvd; - rinfo.header_and_padding_bytes_rcvd = stats.header_and_padding_bytes_rcvd; - rinfo.packets_rcvd = stats.packets_rcvd; + rinfo.payload_bytes_received = stats.payload_bytes_received; + rinfo.header_and_padding_bytes_received = + stats.header_and_padding_bytes_received; + rinfo.packets_received = stats.packets_received; rinfo.fec_packets_received = stats.fec_packets_received; rinfo.fec_packets_discarded = stats.fec_packets_discarded; rinfo.packets_lost = stats.packets_lost; diff --git a/third_party/libwebrtc/media/engine/webrtc_voice_engine.h b/third_party/libwebrtc/media/engine/webrtc_voice_engine.h index 6d25397e68203..f5d8080723d79 100644 --- a/third_party/libwebrtc/media/engine/webrtc_voice_engine.h +++ b/third_party/libwebrtc/media/engine/webrtc_voice_engine.h @@ -110,8 +110,10 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { std::vector CollectCodecs( const std::vector& specs) const; - webrtc::SequenceChecker signal_thread_checker_; - webrtc::SequenceChecker worker_thread_checker_; + webrtc::SequenceChecker signal_thread_checker_{ + webrtc::SequenceChecker::kDetached}; + webrtc::SequenceChecker worker_thread_checker_{ + webrtc::SequenceChecker::kDetached}; // The audio device module. rtc::scoped_refptr adm_; @@ -286,7 +288,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, webrtc::TaskQueueBase* const worker_thread_; webrtc::ScopedTaskSafety task_safety_; - webrtc::SequenceChecker network_thread_checker_; + webrtc::SequenceChecker network_thread_checker_{ + webrtc::SequenceChecker::kDetached}; WebRtcVoiceEngine* const engine_ = nullptr; std::vector send_codecs_; diff --git a/third_party/libwebrtc/media/engine/webrtc_voice_engine_unittest.cc b/third_party/libwebrtc/media/engine/webrtc_voice_engine_unittest.cc index 1393d0b9af364..d151715c3ac9f 100644 --- a/third_party/libwebrtc/media/engine/webrtc_voice_engine_unittest.cc +++ b/third_party/libwebrtc/media/engine/webrtc_voice_engine_unittest.cc @@ -678,9 +678,9 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { const { webrtc::AudioReceiveStreamInterface::Stats stats; stats.remote_ssrc = 123; - stats.payload_bytes_rcvd = 456; - stats.header_and_padding_bytes_rcvd = 67; - stats.packets_rcvd = 768; + stats.payload_bytes_received = 456; + stats.header_and_padding_bytes_received = 67; + stats.packets_received = 768; stats.packets_lost = 101; stats.codec_name = "codec_name_recv"; stats.codec_payload_type = 0; @@ -719,11 +719,11 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam { void VerifyVoiceReceiverInfo(const cricket::VoiceReceiverInfo& info) { const auto stats = GetAudioReceiveStreamStats(); EXPECT_EQ(info.ssrc(), stats.remote_ssrc); - EXPECT_EQ(info.payload_bytes_rcvd, stats.payload_bytes_rcvd); - EXPECT_EQ(info.header_and_padding_bytes_rcvd, - stats.header_and_padding_bytes_rcvd); - EXPECT_EQ(rtc::checked_cast(info.packets_rcvd), - stats.packets_rcvd); + EXPECT_EQ(info.payload_bytes_received, stats.payload_bytes_received); + EXPECT_EQ(info.header_and_padding_bytes_received, + stats.header_and_padding_bytes_received); + EXPECT_EQ(rtc::checked_cast(info.packets_received), + stats.packets_received); EXPECT_EQ(info.packets_lost, stats.packets_lost); EXPECT_EQ(info.codec_name, stats.codec_name); EXPECT_EQ(info.codec_payload_type, stats.codec_payload_type); diff --git a/third_party/libwebrtc/modules/BUILD.gn b/third_party/libwebrtc/modules/BUILD.gn index 229a0ed529836..4870cb349995d 100644 --- a/third_party/libwebrtc/modules/BUILD.gn +++ b/third_party/libwebrtc/modules/BUILD.gn @@ -227,7 +227,6 @@ if (rtc_include_tests && !build_with_chromium) { "pacing:pacing_unittests", "remote_bitrate_estimator:remote_bitrate_estimator_unittests", "rtp_rtcp:rtp_rtcp_unittests", - "utility:utility_unittests", "video_coding:video_coding_unittests", "video_coding/deprecated:deprecated_unittests", "video_coding/timing:timing_unittests", diff --git a/third_party/libwebrtc/modules/audio_coding/BUILD.gn b/third_party/libwebrtc/modules/audio_coding/BUILD.gn index 6c1f812c0fcc8..143a6eca41284 100644 --- a/third_party/libwebrtc/modules/audio_coding/BUILD.gn +++ b/third_party/libwebrtc/modules/audio_coding/BUILD.gn @@ -821,8 +821,8 @@ rtc_library("neteq_test_tools") { "neteq/tools/constant_pcm_packet_source.h", "neteq/tools/initial_packet_inserter_neteq_input.cc", "neteq/tools/initial_packet_inserter_neteq_input.h", - "neteq/tools/neteq_packet_source_input.cc", - "neteq/tools/neteq_packet_source_input.h", + "neteq/tools/neteq_rtp_dump_input.cc", + "neteq/tools/neteq_rtp_dump_input.h", "neteq/tools/output_audio_file.h", "neteq/tools/output_wav_file.h", "neteq/tools/rtp_file_source.cc", @@ -850,14 +850,6 @@ rtc_library("neteq_test_tools") { "//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/types:optional", ] - - if (rtc_enable_protobuf) { - sources += [ - "neteq/tools/neteq_event_log_input.cc", - "neteq/tools/neteq_event_log_input.h", - ] - deps += [ ":rtc_event_log_source" ] - } } rtc_library("neteq_tools") { @@ -893,6 +885,16 @@ rtc_library("neteq_tools") { "//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/types:optional", ] + + if (rtc_enable_protobuf) { + sources += [ + "neteq/tools/neteq_event_log_input.cc", + "neteq/tools/neteq_event_log_input.h", + ] + deps += [ "../../logging:rtc_event_log_parser" ] + public_deps = # no-presubmit-check TODO(webrtc:8603) + [ "../../logging:rtc_event_log_proto" ] + } } rtc_library("neteq_input_audio_tools") { @@ -912,29 +914,6 @@ rtc_library("neteq_input_audio_tools") { } if (rtc_enable_protobuf) { - rtc_library("rtc_event_log_source") { - testonly = true - - sources = [ - "neteq/tools/rtc_event_log_source.cc", - "neteq/tools/rtc_event_log_source.h", - ] - - deps = [ - ":neteq_tools_minimal", - "../../logging:rtc_event_log_parser", - "../../rtc_base:checks", - "../rtp_rtcp", - "../rtp_rtcp:rtp_rtcp_format", - ] - absl_deps = [ - "//third_party/abseil-cpp/absl/strings", - "//third_party/abseil-cpp/absl/types:optional", - ] - public_deps = # no-presubmit-check TODO(webrtc:8603) - [ "../../logging:rtc_event_log_proto" ] - } - # Only used for test purpose. Since we want to use it from chromium # (see audio_coding_modules_tests_shared below), we cannot guard it # under rtc_include_tests. diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc b/third_party/libwebrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc index 4a2b261a5997e..bd8d1cc34115b 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/codecs/builtin_audio_decoder_factory_unittest.cc @@ -98,16 +98,12 @@ TEST(AudioDecoderFactoryTest, MaxNrOfChannels) { CreateBuiltinAudioDecoderFactory(); std::vector codecs = { #ifdef WEBRTC_CODEC_OPUS - "opus", + "opus", #endif #ifdef WEBRTC_CODEC_ILBC - "ilbc", + "ilbc", #endif - "pcmu", - "pcma", - "l16", - "G722", - "G711", + "pcmu", "pcma", "l16", "G722", "G711", }; for (auto codec : codecs) { diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc b/third_party/libwebrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc index 1ecc9bc3d1d18..e969ed1189e3c 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc +++ b/third_party/libwebrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc @@ -94,7 +94,7 @@ int AudioDecoderG722StereoImpl::DecodeInternal(const uint8_t* encoded, const size_t encoded_len_adjusted = PacketDuration(encoded, encoded_len) * Channels() / 2; // 1/2 byte per sample per channel - int16_t temp_type = 1; // Default is speech. + int16_t temp_type = 1; // Default is speech. // De-interleave the bit-stream into two separate payloads. uint8_t* encoded_deinterleaved = new uint8_t[encoded_len_adjusted]; SplitStereoPacket(encoded, encoded_len_adjusted, encoded_deinterleaved); diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/abs_quant.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/abs_quant.h index c72e29cf29b06..4a3f004ed3188 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/abs_quant.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/abs_quant.h @@ -37,6 +37,6 @@ void WebRtcIlbcfix_AbsQuant( input) */ int16_t* in, /* (i) vector to encode */ int16_t* weightDenum /* (i) denominator of synthesis filter */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/bw_expand.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/bw_expand.h index ff9b0b302e402..022c113ddadcd 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/bw_expand.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/bw_expand.h @@ -32,6 +32,6 @@ void WebRtcIlbcfix_BwExpand( expansion */ int16_t* coef, /* (i) the bandwidth expansion factor Q15 */ int16_t length /* (i) the length of lpc coefficient vectors */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.h index 17ec337dc64ad..15dc884f2a488 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy.h @@ -32,6 +32,6 @@ void WebRtcIlbcfix_CbMemEnergy( int16_t* energyShifts, /* (o) Shift value of the energy */ int scale, /* (i) The scaling of all energy values */ size_t base_size /* (i) Index to where energy values should be stored */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.h index d7b7a0d97e327..c489ab54f9d9d 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_augmentation.h @@ -29,6 +29,6 @@ void WebRtcIlbcfix_CbMemEnergyAugmentation( size_t base_size, /* (i) Index to where energy values should be stored */ int16_t* energyW16, /* (o) Energy in the CB vectors */ int16_t* energyShifts /* (o) Shift value of the energy */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.h index 1d1e8d62b9cfa..4b3703182ec9d 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_mem_energy_calc.h @@ -31,6 +31,6 @@ void WebRtcIlbcfix_CbMemEnergyCalc( int16_t* energyShifts, /* (o) Shift value of the energy */ int scale, /* (i) The scaling of all energy values */ size_t base_size /* (i) Index to where energy values should be stored */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search.h index 84a52c7868272..11856649e70ec 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search.h @@ -35,6 +35,6 @@ void WebRtcIlbcfix_CbSearch( size_t lTarget, /* (i) Length of vector */ int16_t* weightDenum, /* (i) weighting filter coefficients in Q12 */ size_t block /* (i) the subblock number */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search_core.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search_core.h index 5da70e098824a..5a3b13e4469a8 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search_core.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/cb_search_core.h @@ -33,9 +33,9 @@ void WebRtcIlbcfix_CbSearchCore( size_t* bestIndex, /* (o) Index that corresponds to maximum criteria (in this vector) */ - int32_t* bestCrit, /* (o) Value of critera for the - chosen index */ - int16_t* bestCritSh); /* (o) The domain of the chosen - criteria */ + int32_t* bestCrit, /* (o) Value of critera for the + chosen index */ + int16_t* bestCritSh); /* (o) The domain of the chosen + criteria */ #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/chebyshev.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/chebyshev.h index 7e7742c5cc6e8..8ba82927b838c 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/chebyshev.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/chebyshev.h @@ -33,6 +33,6 @@ int16_t WebRtcIlbcfix_Chebyshev( /* (o) Result of C(x) */ int16_t x, /* (i) Value to the Chevyshev polynomial */ int16_t* f /* (i) The coefficients in the polynomial */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/comp_corr.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/comp_corr.h index 010c6a1ce5d44..d9df9a78f806b 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/comp_corr.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/comp_corr.h @@ -34,6 +34,6 @@ void WebRtcIlbcfix_CompCorr(int32_t* corr, /* (o) cross correlation */ size_t bLen, /* (i) length of buffer */ size_t sRange, /* (i) correlation search length */ int16_t scale /* (i) number of rightshifts to use */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.h index d7e5be1c2f693..5bed469a12256 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/create_augmented_vec.h @@ -28,8 +28,8 @@ *----------------------------------------------------------------*/ void WebRtcIlbcfix_CreateAugmentedVec( - size_t index, /* (i) Index for the augmented vector to be - created */ + size_t index, /* (i) Index for the augmented vector to be + created */ const int16_t* buffer, /* (i) Pointer to the end of the codebook memory that is used for creation of the augmented codebook */ diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h index 8b081144674c5..40510007a9119 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h @@ -29,13 +29,13 @@ *---------------------------------------------------------------*/ void WebRtcIlbcfix_DecoderInterpolateLsp( - int16_t* syntdenum, /* (o) synthesis filter coefficients */ + int16_t* syntdenum, /* (o) synthesis filter coefficients */ int16_t* weightdenum, /* (o) weighting denumerator coefficients */ - int16_t* lsfdeq, /* (i) dequantized lsf coefficients */ - int16_t length, /* (i) length of lsf coefficient vector */ + int16_t* lsfdeq, /* (i) dequantized lsf coefficients */ + int16_t length, /* (i) length of lsf coefficient vector */ IlbcDecoder* iLBCdec_inst /* (i) the decoder state structure */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/do_plc.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/do_plc.h index c19c4eca32f56..5e3bcc6d3cc45 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/do_plc.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/do_plc.h @@ -39,6 +39,6 @@ void WebRtcIlbcfix_DoThePlc( size_t inlag, /* (i) pitch lag */ IlbcDecoder* iLBCdec_inst /* (i/o) decoder instance */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/encode.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/encode.h index bc3e187d92e99..5290420bbf2f4 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/encode.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/encode.h @@ -29,10 +29,10 @@ *---------------------------------------------------------------*/ void WebRtcIlbcfix_EncodeImpl( - uint16_t* bytes, /* (o) encoded data bits iLBC */ - const int16_t* block, /* (i) speech vector to encode */ + uint16_t* bytes, /* (o) encoded data bits iLBC */ + const int16_t* block, /* (i) speech vector to encode */ IlbcEncoder* iLBCenc_inst /* (i/o) the general encoder state */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/energy_inverse.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/energy_inverse.h index 15391cf230286..3a11488056e73 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/energy_inverse.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/energy_inverse.h @@ -28,8 +28,8 @@ void WebRtcIlbcfix_EnergyInverse( int16_t* - energy, /* (i/o) Energy and inverse - energy (in Q29) */ + energy, /* (i/o) Energy and inverse + energy (in Q29) */ size_t noOfEnergies); /* (i) The length of the energy vector */ diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enh_upsample.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enh_upsample.h index b427eca50a758..20c85fb20ec23 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enh_upsample.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enh_upsample.h @@ -28,6 +28,6 @@ void WebRtcIlbcfix_EnhUpsample( int32_t* useq1, /* (o) upsampled output sequence */ int16_t* seq1 /* (i) unupsampled sequence */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enhancer.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enhancer.h index 386949347ae7d..0c631bcb86329 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enhancer.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/enhancer.h @@ -35,6 +35,6 @@ void WebRtcIlbcfix_Enhancer( size_t* period, /* (i) pitch period array (pitch bward-in time) */ const size_t* plocs, /* (i) locations where period array values valid */ size_t periodl /* (i) dimension of period and plocs */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.h index 661262e42eb9b..d0f5f1a4ed529 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/filtered_cb_vecs.h @@ -34,6 +34,6 @@ void WebRtcIlbcfix_FilteredCbVecs( second CB section */ size_t lMem, /* (i) Length of codebook memory */ size_t samples /* (i) Number of samples to filter */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/frame_classify.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/frame_classify.h index 7615106d70f56..dee67cc5f9328 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/frame_classify.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/frame_classify.h @@ -29,6 +29,6 @@ size_t WebRtcIlbcfix_FrameClassify( IlbcEncoder* iLBCenc_inst, /* (i/o) the encoder state structure */ int16_t* residualFIX /* (i) lpc residual signal */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_dequant.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_dequant.h index 2b97550b6ccae..b5e6cef97b7f2 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_dequant.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_dequant.h @@ -31,6 +31,6 @@ int16_t WebRtcIlbcfix_GainDequant( int16_t index, /* (i) quantization index */ int16_t maxIn, /* (i) maximum of unquantized gain (Q14) */ int16_t stage /* (i) The stage of the search */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_quant.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_quant.h index 761f7d2f7906f..fab9718a751a3 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_quant.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/gain_quant.h @@ -31,6 +31,6 @@ WebRtcIlbcfix_GainQuant( /* (o) quantized gain value */ int16_t maxIn, /* (i) maximum of gain value Q14 */ int16_t stage, /* (i) The stage of the search */ int16_t* index /* (o) quantization index */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.h index 90962fa063246..87030e568fec9 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/get_sync_seq.h @@ -36,6 +36,6 @@ void WebRtcIlbcfix_GetSyncSeq( size_t hl, /* (i) 2*hl+1 is the number of sequences */ int16_t* surround /* (i/o) The contribution from this sequence summed with earlier contributions */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.h index 4f08ce04dfbda..4d3f7333555f6 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_dec.h @@ -22,6 +22,6 @@ #include "modules/audio_coding/codecs/ilbc/defines.h" void WebRtcIlbcfix_IndexConvDec(int16_t* index /* (i/o) Codebook indexes */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.h index 4fbf98084e999..0172ac416bce9 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/index_conv_enc.h @@ -26,6 +26,6 @@ *---------------------------------------------------------------*/ void WebRtcIlbcfix_IndexConvEnc(int16_t* index /* (i/o) Codebook indexes */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_decode.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_decode.h index a2b7b91287828..92f9ad68e7571 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_decode.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_decode.h @@ -33,6 +33,6 @@ int WebRtcIlbcfix_InitDecode(/* (o) Number of decoded samples */ int16_t mode, /* (i) frame size mode */ int use_enhancer /* (i) 1 to use enhancer 0 to run without enhancer */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_encode.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_encode.h index 4ada6a30c8a05..4a233fb9463ff 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_encode.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/init_encode.h @@ -31,6 +31,6 @@ int WebRtcIlbcfix_InitEncode(/* (o) Number of bytes encoded */ IlbcEncoder* iLBCenc_inst, /* (i/o) Encoder instance */ int16_t mode /* (i) frame size mode */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.h index bc665d7854140..f4fa97d47732a 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/interpolate_samples.h @@ -30,6 +30,6 @@ void WebRtcIlbcfix_InterpolateSamples( int16_t* interpSamples, /* (o) The interpolated samples */ int16_t* CBmem, /* (i) The CB memory */ size_t lMem /* (i) Length of the CB memory */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lpc_encode.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lpc_encode.h index a67b77acbfa44..ca050b02cc8c5 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lpc_encode.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lpc_encode.h @@ -37,6 +37,6 @@ void WebRtcIlbcfix_LpcEncode( int16_t* data, /* (i) Speech to do LPC analysis on */ IlbcEncoder* iLBCenc_inst /* (i/o) the encoder state structure */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.h index 6cc9d9746d7ec..a0ccfa96acc8b 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_dec.h @@ -32,6 +32,6 @@ void WebRtcIlbcfix_LspInterpolate2PolyDec( int16_t coef, /* (i) weighting coefficient to use between lsf1 and lsf2 Q14 */ int16_t length /* (i) length of coefficient vectors */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.h index b278a10f4b776..08d1e8325a598 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_interpolate_to_poly_enc.h @@ -33,6 +33,6 @@ void WebRtcIlbcfix_LsfInterpolate2PloyEnc( int16_t coef, /* (i) weighting coefficient to use between lsf1 and lsf2 Q14 */ int16_t length /* (i) length of coefficient vectors */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.h index 6bc6c44dbd3d2..fccc3c2b1c521 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_lsp.h @@ -29,6 +29,6 @@ void WebRtcIlbcfix_Lsf2Lsp( int16_t* lsf, /* (i) lsf in Q13 values between 0 and pi */ int16_t* lsp, /* (o) lsp in Q15 values between -1 and 1 */ int16_t m /* (i) number of coefficients */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.h index f26d3a8d2dd5c..06f292f038627 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsf_to_poly.h @@ -28,6 +28,6 @@ void WebRtcIlbcfix_Lsf2Poly( int16_t* a, /* (o) predictor coefficients (order = 10) in Q12 */ int16_t* lsf /* (i) line spectral frequencies in Q13 */ - ); +); #endif diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.h b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.h index c2f4b7692dbc3..a0dfb8e8eb27b 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.h +++ b/third_party/libwebrtc/modules/audio_coding/codecs/ilbc/lsp_to_lsf.h @@ -30,6 +30,6 @@ void WebRtcIlbcfix_Lsp2Lsf( int16_t* lsf, /* (o) Lsf vector 0...Pi in Q13 (ordered, so that lsf[i] - #include #include "api/array_view.h" diff --git a/third_party/libwebrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/third_party/libwebrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc index 795a996624a80..8161931a7ab75 100644 --- a/third_party/libwebrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc @@ -37,7 +37,7 @@ namespace { static const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo. static const size_t kRedLastHeaderLength = 1; // 1 byte RED header for the last element. -} +} // namespace class AudioEncoderCopyRedTest : public ::testing::Test { protected: diff --git a/third_party/libwebrtc/modules/audio_coding/include/audio_coding_module_typedefs.h b/third_party/libwebrtc/modules/audio_coding/include/audio_coding_module_typedefs.h index 9d2fcfe22e37b..4b880fb6338fe 100644 --- a/third_party/libwebrtc/modules/audio_coding/include/audio_coding_module_typedefs.h +++ b/third_party/libwebrtc/modules/audio_coding/include/audio_coding_module_typedefs.h @@ -64,7 +64,7 @@ struct AudioDecodingCallStats { int calls_to_silence_generator; // Number of calls where silence generated, // and NetEq was disengaged from decoding. int calls_to_neteq; // Number of calls to NetEq. - int decoded_normal; // Number of calls where audio RTP packet decoded. + int decoded_normal; // Number of calls where audio RTP packet decoded. int decoded_neteq_plc; // Number of calls resulted in NetEq PLC. int decoded_codec_plc; // Number of calls resulted in codec PLC. int decoded_cng; // Number of calls where comfort noise generated due to DTX. diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/accelerate.cc b/third_party/libwebrtc/modules/audio_coding/neteq/accelerate.cc index f4ef6cdccb589..06a38cc534181 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/accelerate.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/accelerate.cc @@ -10,7 +10,6 @@ #include "modules/audio_coding/neteq/accelerate.h" - #include "api/array_view.h" #include "modules/audio_coding/neteq/audio_multi_vector.h" diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/audio_multi_vector.cc b/third_party/libwebrtc/modules/audio_coding/neteq/audio_multi_vector.cc index 14ae94649b522..3aa49e5b9af62 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/audio_multi_vector.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/audio_multi_vector.cc @@ -10,7 +10,6 @@ #include "modules/audio_coding/neteq/audio_multi_vector.h" - #include #include "rtc_base/checks.h" diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/audio_vector.cc b/third_party/libwebrtc/modules/audio_coding/neteq/audio_vector.cc index 10e89364475cb..89105949d504b 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/audio_vector.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/audio_vector.cc @@ -10,7 +10,6 @@ #include "modules/audio_coding/neteq/audio_vector.h" - #include #include diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/buffer_level_filter.cc b/third_party/libwebrtc/modules/audio_coding/neteq/buffer_level_filter.cc index 2c42d0d13fd43..948545d9488a6 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/buffer_level_filter.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/buffer_level_filter.cc @@ -35,7 +35,7 @@ void BufferLevelFilter::Update(size_t buffer_size_samples, // `level_factor_` and `filtered_current_level_` are in Q8. // `buffer_size_samples` is in Q0. const int64_t filtered_current_level = - (level_factor_ * int64_t{filtered_current_level_} >> 8) + + (level_factor_* int64_t{filtered_current_level_} >> 8) + (256 - level_factor_) * rtc::dchecked_cast(buffer_size_samples); // Account for time-scale operations (accelerate and pre-emptive expand) and diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/comfort_noise.cc b/third_party/libwebrtc/modules/audio_coding/neteq/comfort_noise.cc index a2ce888f4519b..8a906593d7708 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/comfort_noise.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/comfort_noise.cc @@ -10,7 +10,6 @@ #include "modules/audio_coding/neteq/comfort_noise.h" - #include #include diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.cc b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.cc index 32b9f1c95a9e3..fd4f2f5a20085 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.cc @@ -69,7 +69,7 @@ bool IsExpand(NetEq::Mode mode) { DecisionLogic::Config::Config() { StructParametersParser::Create( - "enable_stable_playout_delay", &enable_stable_playout_delay, // + "enable_stable_delay_mode", &enable_stable_delay_mode, // "combine_concealment_decision", &combine_concealment_decision, // "packet_history_size_ms", &packet_history_size_ms, // "cng_timeout_ms", &cng_timeout_ms, // @@ -78,8 +78,7 @@ DecisionLogic::Config::Config() { ->Parse(webrtc::field_trial::FindFullName( "WebRTC-Audio-NetEqDecisionLogicConfig")); RTC_LOG(LS_INFO) << "NetEq decision logic config:" - << " enable_stable_playout_delay=" - << enable_stable_playout_delay + << " enable_stable_delay_mode=" << enable_stable_delay_mode << " combine_concealment_decision=" << combine_concealment_decision << " packet_history_size_ms=" << packet_history_size_ms @@ -117,7 +116,6 @@ void DecisionLogic::SoftReset() { delay_manager_->Reset(); buffer_level_filter_->Reset(); packet_arrival_history_.Reset(); - last_playout_delay_ms_ = 0; } void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { @@ -131,10 +129,6 @@ void DecisionLogic::SetSampleRate(int fs_hz, size_t output_size_samples) { NetEq::Operation DecisionLogic::GetDecision(const NetEqStatus& status, bool* reset_decoder) { - if (!IsExpand(status.last_mode) && !IsCng(status.last_mode)) { - last_playout_delay_ms_ = GetPlayoutDelayMs(status); - } - prev_time_scale_ = prev_time_scale_ && IsTimestretch(status.last_mode); if (prev_time_scale_) { timescale_countdown_ = tick_timer_->GetNewCountdown(kMinTimescaleInterval); @@ -194,7 +188,7 @@ NetEq::Operation DecisionLogic::GetDecision(const NetEqStatus& status, int DecisionLogic::TargetLevelMs() const { int target_delay_ms = delay_manager_->TargetDelayMs(); - if (!config_.enable_stable_playout_delay) { + if (!config_.enable_stable_delay_mode) { target_delay_ms = std::max(target_delay_ms, static_cast(packet_length_samples_ / sample_rate_khz_)); @@ -207,9 +201,6 @@ int DecisionLogic::UnlimitedTargetLevelMs() const { } int DecisionLogic::GetFilteredBufferLevel() const { - if (config_.enable_stable_playout_delay) { - return last_playout_delay_ms_ * sample_rate_khz_; - } return buffer_level_filter_->filtered_current_level(); } @@ -313,16 +304,20 @@ NetEq::Operation DecisionLogic::ExpectedPacketAvailable( NetEqController::NetEqStatus status) { if (!disallow_time_stretching_ && status.last_mode != NetEq::Mode::kExpand && !status.play_dtmf) { - if (config_.enable_stable_playout_delay) { + if (config_.enable_stable_delay_mode) { const int playout_delay_ms = GetPlayoutDelayMs(status); - if (playout_delay_ms >= HighThreshold() << 2) { + const int low_limit = TargetLevelMs(); + const int high_limit = low_limit + + packet_arrival_history_.GetMaxDelayMs() + + kDelayAdjustmentGranularityMs; + if (playout_delay_ms >= high_limit * 4) { return NetEq::Operation::kFastAccelerate; } if (TimescaleAllowed()) { - if (playout_delay_ms >= HighThreshold()) { + if (playout_delay_ms >= high_limit) { return NetEq::Operation::kAccelerate; } - if (playout_delay_ms < LowThreshold()) { + if (playout_delay_ms < low_limit) { return NetEq::Operation::kPreemptiveExpand; } } @@ -338,7 +333,7 @@ NetEq::Operation DecisionLogic::ExpectedPacketAvailable( const int buffer_level_samples = buffer_level_filter_->filtered_current_level(); - if (buffer_level_samples >= high_limit << 2) + if (buffer_level_samples >= high_limit * 4) return NetEq::Operation::kFastAccelerate; if (TimescaleAllowed()) { if (buffer_level_samples >= high_limit) @@ -357,10 +352,16 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( // Check if we should continue with an ongoing concealment because the new // packet is too far into the future. if (config_.combine_concealment_decision || IsCng(status.last_mode)) { - const int buffer_delay_ms = - status.packet_buffer_info.span_samples / sample_rate_khz_; - const bool above_target_delay = buffer_delay_ms > HighThresholdCng(); - const bool below_target_delay = buffer_delay_ms < LowThresholdCng(); + const int buffer_delay_samples = + config_.combine_concealment_decision + ? status.packet_buffer_info.span_samples_wait_time + : status.packet_buffer_info.span_samples; + const int buffer_delay_ms = buffer_delay_samples / sample_rate_khz_; + const int high_limit = TargetLevelMs() + kTargetLevelWindowMs / 2; + const int low_limit = + std::max(0, TargetLevelMs() - kTargetLevelWindowMs / 2); + const bool above_target_delay = buffer_delay_ms > high_limit; + const bool below_target_delay = buffer_delay_ms < low_limit; if ((PacketTooEarly(status) && !above_target_delay) || (below_target_delay && !config_.combine_concealment_decision)) { return NoPacket(status); @@ -370,8 +371,7 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( if (config_.combine_concealment_decision) { if (timestamp_leap != status.generated_noise_samples) { // The delay was adjusted, reinitialize the buffer level filter. - buffer_level_filter_->SetFilteredBufferLevel( - status.packet_buffer_info.span_samples); + buffer_level_filter_->SetFilteredBufferLevel(buffer_delay_samples); } } else { time_stretched_cn_samples_ = @@ -405,7 +405,11 @@ bool DecisionLogic::PostponeDecode(NetEqController::NetEqStatus status) const { // running out of data right away again. const size_t min_buffer_level_samples = TargetLevelMs() * sample_rate_khz_ * kPostponeDecodingLevel / 100; - if (status.packet_buffer_info.span_samples >= min_buffer_level_samples) { + const size_t buffer_level_samples = + config_.combine_concealment_decision + ? status.packet_buffer_info.span_samples_wait_time + : status.packet_buffer_info.span_samples; + if (buffer_level_samples >= min_buffer_level_samples) { return false; } // Don't postpone decoding if there is a future DTX packet in the packet @@ -448,24 +452,10 @@ bool DecisionLogic::MaxWaitForPacket( bool DecisionLogic::ShouldContinueExpand( NetEqController::NetEqStatus status) const { - if (config_.enable_stable_playout_delay) { - return GetNextPacketDelayMs(status) < HighThreshold() && - PacketTooEarly(status); - } return !ReinitAfterExpands(status) && !MaxWaitForPacket(status) && PacketTooEarly(status) && UnderTargetLevel(); } -int DecisionLogic::GetNextPacketDelayMs( - NetEqController::NetEqStatus status) const { - if (config_.enable_stable_playout_delay) { - return packet_arrival_history_.GetDelayMs( - status.next_packet->timestamp, - tick_timer_->ticks() * tick_timer_->ms_per_tick()); - } - return status.packet_buffer_info.span_samples / sample_rate_khz_; -} - int DecisionLogic::GetPlayoutDelayMs( NetEqController::NetEqStatus status) const { uint32_t playout_timestamp = @@ -474,34 +464,4 @@ int DecisionLogic::GetPlayoutDelayMs( playout_timestamp, tick_timer_->ticks() * tick_timer_->ms_per_tick()); } -int DecisionLogic::LowThreshold() const { - int target_delay_ms = TargetLevelMs(); - return std::max( - target_delay_ms * 3 / 4, - target_delay_ms - config_.deceleration_target_level_offset_ms); -} - -int DecisionLogic::HighThreshold() const { - if (config_.enable_stable_playout_delay) { - return std::max(TargetLevelMs(), packet_arrival_history_.GetMaxDelayMs()) + - kDelayAdjustmentGranularityMs; - } - return std::max(TargetLevelMs(), - LowThreshold() + kDelayAdjustmentGranularityMs); -} - -int DecisionLogic::LowThresholdCng() const { - if (config_.enable_stable_playout_delay) { - return LowThreshold(); - } - return std::max(0, TargetLevelMs() - kTargetLevelWindowMs / 2); -} - -int DecisionLogic::HighThresholdCng() const { - if (config_.enable_stable_playout_delay) { - return HighThreshold(); - } - return TargetLevelMs() + kTargetLevelWindowMs / 2; -} - } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.h b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.h index 2f885d96ea10b..d96fbecd6a056 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic.h @@ -147,20 +147,14 @@ class DecisionLogic : public NetEqController { bool PacketTooEarly(NetEqController::NetEqStatus status) const; bool MaxWaitForPacket(NetEqController::NetEqStatus status) const; bool ShouldContinueExpand(NetEqController::NetEqStatus status) const; - int GetNextPacketDelayMs(NetEqController::NetEqStatus status) const; int GetPlayoutDelayMs(NetEqController::NetEqStatus status) const; - int LowThreshold() const; - int HighThreshold() const; - int LowThresholdCng() const; - int HighThresholdCng() const; - // Runtime configurable options through field trial // WebRTC-Audio-NetEqDecisionLogicConfig. struct Config { Config(); - bool enable_stable_playout_delay = false; + bool enable_stable_delay_mode = false; bool combine_concealment_decision = false; int deceleration_target_level_offset_ms = 85; int packet_history_size_ms = 2000; @@ -181,7 +175,6 @@ class DecisionLogic : public NetEqController { std::unique_ptr timescale_countdown_; int time_stretched_cn_samples_ = 0; bool buffer_flush_ = false; - int last_playout_delay_ms_ = 0; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic_unittest.cc index 6150c9a6db6aa..97e20dd88350a 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/decision_logic_unittest.cc @@ -40,7 +40,7 @@ NetEqController::NetEqStatus CreateNetEqStatus(NetEq::Mode last_mode, status.expand_mutefactor = 0; status.packet_buffer_info.num_samples = current_delay_ms * kSamplesPerMs; status.packet_buffer_info.span_samples = current_delay_ms * kSamplesPerMs; - status.packet_buffer_info.span_samples_no_dtx = + status.packet_buffer_info.span_samples_wait_time = current_delay_ms * kSamplesPerMs; status.packet_buffer_info.dtx_or_cng = false; status.next_packet = {status.target_timestamp, false, false}; diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/expand.h b/third_party/libwebrtc/modules/audio_coding/neteq/expand.h index 2e64583ec272d..bd58788ae032c 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/expand.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/expand.h @@ -11,7 +11,6 @@ #ifndef MODULES_AUDIO_CODING_NETEQ_EXPAND_H_ #define MODULES_AUDIO_CODING_NETEQ_EXPAND_H_ - #include #include "modules/audio_coding/neteq/audio_vector.h" diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/histogram.cc b/third_party/libwebrtc/modules/audio_coding/neteq/histogram.cc index e4b7f10379e10..4360d1a9043f5 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/histogram.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/histogram.cc @@ -114,8 +114,8 @@ int Histogram::Quantile(int probability) { // `iat_index`, it is more efficient to start with `sum` = 1 and subtract // elements from the start of the histogram. int inverse_probability = (1 << 30) - probability; - size_t index = 0; // Start from the beginning of `buckets_`. - int sum = 1 << 30; // Assign to 1 in Q30. + size_t index = 0; // Start from the beginning of `buckets_`. + int sum = 1 << 30; // Assign to 1 in Q30. sum -= buckets_[index]; while ((sum > inverse_probability) && (index < buckets_.size() - 1)) { diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.cc b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.cc index 04cc5b52e8f08..71c6fc3048fa3 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.cc @@ -145,43 +145,22 @@ uint32_t NackTracker::EstimateTimestamp(uint16_t sequence_num, return sequence_num_diff * samples_per_packet + timestamp_last_received_rtp_; } -void NackTracker::UpdateEstimatedPlayoutTimeBy10ms() { - while (!nack_list_.empty() && - nack_list_.begin()->second.time_to_play_ms <= 10) - nack_list_.erase(nack_list_.begin()); - - for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); ++it) - it->second.time_to_play_ms -= 10; -} - void NackTracker::UpdateLastDecodedPacket(uint16_t sequence_number, uint32_t timestamp) { - if (IsNewerSequenceNumber(sequence_number, sequence_num_last_decoded_rtp_) || - !any_rtp_decoded_) { - sequence_num_last_decoded_rtp_ = sequence_number; - timestamp_last_decoded_rtp_ = timestamp; - // Packets in the list with sequence numbers less than the - // sequence number of the decoded RTP should be removed from the lists. - // They will be discarded by the jitter buffer if they arrive. - nack_list_.erase(nack_list_.begin(), - nack_list_.upper_bound(sequence_num_last_decoded_rtp_)); - - // Update estimated time-to-play. - for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); - ++it) - it->second.time_to_play_ms = TimeToPlay(it->second.estimated_timestamp); - } else { - RTC_DCHECK_EQ(sequence_number, sequence_num_last_decoded_rtp_); - - // Same sequence number as before. 10 ms is elapsed, update estimations for - // time-to-play. - UpdateEstimatedPlayoutTimeBy10ms(); - - // Update timestamp for better estimate of time-to-play, for packets which - // are added to NACK list later on. - timestamp_last_decoded_rtp_ += sample_rate_khz_ * 10; - } any_rtp_decoded_ = true; + sequence_num_last_decoded_rtp_ = sequence_number; + timestamp_last_decoded_rtp_ = timestamp; + // Packets in the list with sequence numbers less than the + // sequence number of the decoded RTP should be removed from the lists. + // They will be discarded by the jitter buffer if they arrive. + nack_list_.erase(nack_list_.begin(), + nack_list_.upper_bound(sequence_num_last_decoded_rtp_)); + + // Update estimated time-to-play. + for (NackList::iterator it = nack_list_.begin(); it != nack_list_.end(); + ++it) { + it->second.time_to_play_ms = TimeToPlay(it->second.estimated_timestamp); + } } NackTracker::NackList NackTracker::GetNackList() const { diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.h b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.h index 14ba2166d1539..d9005da0858fc 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker.h @@ -72,8 +72,7 @@ class NackTracker { // After Reset() is called sampling rate has to be set. void UpdateSampleRate(int sample_rate_hz); - // Update the sequence number and the timestamp of the last decoded RTP. This - // API should be called every time 10 ms audio is pulled from NetEq. + // Update the sequence number and the timestamp of the last decoded RTP. void UpdateLastDecodedPacket(uint16_t sequence_number, uint32_t timestamp); // Update the sequence number and the timestamp of the last received RTP. This @@ -149,10 +148,6 @@ class NackTracker { // computed correctly. NackList GetNackList() const; - // This function subtracts 10 ms of time-to-play for all packets in NACK list. - // This is called when 10 ms elapsed with no new RTP packet decoded. - void UpdateEstimatedPlayoutTimeBy10ms(); - // Returns a valid number of samples per packet given the current received // sequence number and timestamp or nullopt of none could be computed. absl::optional GetSamplesPerPacket( diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker_unittest.cc index bcc5120ff326f..a843425b78b8a 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/nack_tracker_unittest.cc @@ -238,19 +238,6 @@ TEST(NackTrackerTest, EstimateTimestampAndTimeToPlay) { EXPECT_EQ((index + 2) * kPacketSizeMs, it->second.time_to_play_ms); ++it; } - - // Pretend 10 ms is passed, and we had pulled audio from NetEq, it still - // reports the same sequence number as decoded, time-to-play should be - // updated by 10 ms. - nack.UpdateLastDecodedPacket(first_seq_num, first_timestamp); - nack_list = nack.GetNackList(); - it = nack_list.begin(); - while (it != nack_list.end()) { - seq_num = it->first - seq_num_offset; - int index = seq_num - kLostPackets[0]; - EXPECT_EQ((index + 2) * kPacketSizeMs - 10, it->second.time_to_play_ms); - ++it; - } } } diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.cc b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.cc index 2c19e7e213f87..113215db8efdf 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.cc @@ -821,6 +821,9 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, const size_t start_num_packets = packet_list.size(); int decode_return_value = Decode(&packet_list, &operation, &length, &speech_type); + if (length > 0) { + last_decoded_type_ = speech_type; + } RTC_DCHECK(vad_.get()); bool sid_frame_available = @@ -1100,10 +1103,10 @@ int NetEqImpl::GetDecision(Operation* operation, status.packet_buffer_info.num_samples = packet_buffer_->NumSamplesInBuffer(decoder_frame_length_); status.packet_buffer_info.span_samples = packet_buffer_->GetSpanSamples( - decoder_frame_length_, last_output_sample_rate_hz_, true); - status.packet_buffer_info.span_samples_no_dtx = + decoder_frame_length_, last_output_sample_rate_hz_, false); + status.packet_buffer_info.span_samples_wait_time = packet_buffer_->GetSpanSamples(decoder_frame_length_, - last_output_sample_rate_hz_, false); + last_output_sample_rate_hz_, true); status.packet_buffer_info.num_packets = packet_buffer_->NumPacketsInBuffer(); status.target_timestamp = sync_buffer_->end_timestamp(); status.expand_mutefactor = expand_->MuteFactor(0); @@ -1545,7 +1548,7 @@ void NetEqImpl::DoMerge(int16_t* decoded_buffer, rtc::dchecked_cast(decoded_length / algorithm_buffer_->Channels()); // Update in-call and post-call statistics. - if (expand_->MuteFactor(0) == 0) { + if (expand_->Muted() || last_decoded_type_ == AudioDecoder::kComfortNoise) { // Expand generates only noise. stats_->ExpandedNoiseSamplesCorrection(expand_length_correction); } else { @@ -1615,7 +1618,7 @@ int NetEqImpl::DoExpand(bool play_dtmf) { bool is_new_concealment_event = (last_mode_ != Mode::kExpand); // Update in-call and post-call statistics. - if (expand_->MuteFactor(0) == 0) { + if (expand_->Muted() || last_decoded_type_ == AudioDecoder::kComfortNoise) { // Expand operation generates only noise. stats_->ExpandedNoiseSamples(length, is_new_concealment_event); } else { @@ -1937,9 +1940,6 @@ int NetEqImpl::DtmfOverdub(const DtmfEvent& dtmf_event, int NetEqImpl::ExtractPackets(size_t required_samples, PacketList* packet_list) { bool first_packet = true; - uint8_t prev_payload_type = 0; - uint32_t prev_timestamp = 0; - uint16_t prev_sequence_number = 0; bool next_packet_available = false; const Packet* next_packet = packet_buffer_->PeekNextPacket(); @@ -1975,9 +1975,6 @@ int NetEqImpl::ExtractPackets(size_t required_samples, nack_->UpdateLastDecodedPacket(packet->sequence_number, packet->timestamp); } - prev_sequence_number = packet->sequence_number; - prev_timestamp = packet->timestamp; - prev_payload_type = packet->payload_type; } const bool has_cng_packet = @@ -2009,25 +2006,15 @@ int NetEqImpl::ExtractPackets(size_t required_samples, controller_->TargetLevelMs(), controller_->UnlimitedTargetLevelMs()); - packet_list->push_back(std::move(*packet)); // Store packet in list. - packet = absl::nullopt; // Ensure it's never used after the move. - // Check what packet is available next. next_packet = packet_buffer_->PeekNextPacket(); - next_packet_available = false; - if (next_packet && prev_payload_type == next_packet->payload_type && - !has_cng_packet) { - int16_t seq_no_diff = next_packet->sequence_number - prev_sequence_number; - size_t ts_diff = next_packet->timestamp - prev_timestamp; - if ((seq_no_diff == 1 || seq_no_diff == 0) && - ts_diff <= packet_duration) { - // The next sequence number is available, or the next part of a packet - // that was split into pieces upon insertion. - next_packet_available = true; - } - prev_sequence_number = next_packet->sequence_number; - prev_timestamp = next_packet->timestamp; - } + next_packet_available = + next_packet && next_packet->payload_type == packet->payload_type && + next_packet->timestamp == packet->timestamp + packet_duration && + !has_cng_packet; + + packet_list->push_back(std::move(*packet)); // Store packet in list. + packet = absl::nullopt; // Ensure it's never used after the move. } while (extracted_samples < required_samples && next_packet_available); if (extracted_samples > 0) { diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.h b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.h index 6120eab5b6442..f27738bcbf5fe 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl.h @@ -376,6 +376,8 @@ class NetEqImpl : public webrtc::NetEq { size_t decoder_frame_length_ RTC_GUARDED_BY(mutex_); Mode last_mode_ RTC_GUARDED_BY(mutex_); Operation last_operation_ RTC_GUARDED_BY(mutex_); + absl::optional last_decoded_type_ + RTC_GUARDED_BY(mutex_); size_t decoded_buffer_length_ RTC_GUARDED_BY(mutex_); std::unique_ptr decoded_buffer_ RTC_GUARDED_BY(mutex_); uint32_t playout_timestamp_ RTC_GUARDED_BY(mutex_); diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc index 6d68fab7fdfc4..f631937535046 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -393,7 +393,7 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { const int kPayloadLengthSamples = 80; const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit. - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. uint8_t payload[kPayloadLengthBytes] = {0}; RTPHeader rtp_header; rtp_header.payloadType = kPayloadType; @@ -440,7 +440,7 @@ TEST_F(NetEqImplTest, TestDtmfPacketAVT48kHz) { // This test verifies that timestamps propagate from the incoming packets // through to the sync buffer and to the playout timestamp. TEST_F(NetEqImplTest, VerifyTimestampPropagation) { - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const size_t kPayloadLengthSamples = static_cast(10 * kSampleRateHz / 1000); // 10 ms. @@ -559,7 +559,7 @@ TEST_F(NetEqImplTest, ReorderedPacket) { CreateInstance( rtc::make_ref_counted(&mock_decoder)); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const size_t kPayloadLengthSamples = static_cast(10 * kSampleRateHz / 1000); // 10 ms. @@ -674,7 +674,7 @@ TEST_F(NetEqImplTest, FirstPacketUnknown) { UseNoMocks(); CreateInstance(); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const size_t kPayloadLengthSamples = static_cast(10 * kSampleRateHz / 1000); // 10 ms. @@ -767,7 +767,7 @@ TEST_P(NetEqImplTestSampleRateParameter, UseNoMocks(); CreateInstance(); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kPayloadSampleRateHz = 16000; const size_t kPayloadLengthSamples = static_cast(10 * kPayloadSampleRateHz / 1000); // 10 ms. @@ -1004,7 +1004,7 @@ TEST_F(NetEqImplTest, CodecInternalCng) { CreateInstance( rtc::make_ref_counted(&mock_decoder)); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateKhz = 48; const size_t kPayloadLengthSamples = static_cast(20 * kSampleRateKhz); // 20 ms. @@ -1097,7 +1097,7 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) { static const size_t kNetEqMaxFrameSize = 5760; // 120 ms @ 48 kHz. static const size_t kChannels = 2; - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const size_t kPayloadLengthSamples = @@ -1189,7 +1189,7 @@ TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) { const size_t kPayloadLengthSamples = 80; const size_t kPayloadLengthBytes = 2 * kPayloadLengthSamples; // PCM 16-bit. - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. uint8_t payload[kPayloadLengthBytes] = {0}; RTPHeader rtp_header; rtp_header.payloadType = kPayloadType; @@ -1222,7 +1222,7 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) { CreateInstance( rtc::make_ref_counted(&mock_decoder)); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const size_t kPayloadLengthSamples = static_cast(10 * kSampleRateHz / 1000); // 10 ms. @@ -1281,7 +1281,7 @@ TEST_F(NetEqImplTest, DecodingError) { CreateInstance( rtc::make_ref_counted(&mock_decoder)); - const uint8_t kPayloadType = 17; // Just an arbitrary number. + const uint8_t kPayloadType = 17; // Just an arbitrary number. const int kSampleRateHz = 8000; const int kDecoderErrorCode = -97; // Any negative number. diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_unittest.cc index fff14bf830437..77bd5b5035633 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/neteq_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/neteq_unittest.cc @@ -26,7 +26,7 @@ #include "modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "modules/audio_coding/neteq/test/neteq_decoding_test.h" #include "modules/audio_coding/neteq/tools/audio_loop.h" -#include "modules/audio_coding/neteq/tools/neteq_packet_source_input.h" +#include "modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h" #include "modules/audio_coding/neteq/tools/neteq_test.h" #include "modules/include/module_common_types_public.h" #include "modules/rtp_rtcp/include/rtcp_statistics.h" @@ -160,7 +160,6 @@ TEST_F(NetEqDecodingTestFaxMode, TestFrameWaitingTimeStatistics) { EXPECT_EQ(-1, stats.max_waiting_time_ms); } - TEST_F(NetEqDecodingTest, LongCngWithNegativeClockDrift) { // Apply a clock drift of -25 ms / s (sender faster than receiver). const double kDriftFactor = 1000.0 / (1000.0 + 25.0); @@ -982,15 +981,15 @@ TEST(NetEqNoTimeStretchingMode, RunTest) { NetEq::Config config; config.for_test_no_time_stretching = true; auto codecs = NetEqTest::StandardDecoderMap(); - NetEqPacketSourceInput::RtpHeaderExtensionMap rtp_ext_map = { + std::map rtp_ext_map = { {1, kRtpExtensionAudioLevel}, {3, kRtpExtensionAbsoluteSendTime}, {5, kRtpExtensionTransportSequenceNumber}, {7, kRtpExtensionVideoContentType}, {8, kRtpExtensionVideoTiming}}; - std::unique_ptr input(new NetEqRtpDumpInput( + std::unique_ptr input = CreateNetEqRtpDumpInput( webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"), - rtp_ext_map, absl::nullopt /*No SSRC filter*/)); + rtp_ext_map, absl::nullopt /*No SSRC filter*/); std::unique_ptr input_time_limit( new TimeLimitedNetEqInput(std::move(input), 20000)); std::unique_ptr output(new VoidAudioSink); diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.cc b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.cc index f6b5a476c9a56..9bfa908ab90f5 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.cc @@ -119,7 +119,7 @@ void PacketBuffer::PartialFlush(int target_level_ms, // We should avoid flushing to very low levels. target_level_samples = std::max( target_level_samples, smart_flushing_config_->target_level_threshold_ms); - while (GetSpanSamples(last_decoded_length, sample_rate, true) > + while (GetSpanSamples(last_decoded_length, sample_rate, false) > static_cast(target_level_samples) || buffer_.size() > max_number_of_packets_ / 2) { LogPacketDiscarded(PeekNextPacket()->priority.codec_level, stats); @@ -160,7 +160,7 @@ int PacketBuffer::InsertPacket(Packet&& packet, : 0; const bool smart_flush = smart_flushing_config_.has_value() && - GetSpanSamples(last_decoded_length, sample_rate, true) >= span_threshold; + GetSpanSamples(last_decoded_length, sample_rate, false) >= span_threshold; if (buffer_.size() >= max_number_of_packets_ || smart_flush) { size_t buffer_size_before_flush = buffer_.size(); if (smart_flushing_config_.has_value()) { @@ -370,17 +370,19 @@ size_t PacketBuffer::NumSamplesInBuffer(size_t last_decoded_length) const { size_t PacketBuffer::GetSpanSamples(size_t last_decoded_length, size_t sample_rate, - bool count_dtx_waiting_time) const { + bool count_waiting_time) const { if (buffer_.size() == 0) { return 0; } size_t span = buffer_.back().timestamp - buffer_.front().timestamp; - if (buffer_.back().frame && buffer_.back().frame->Duration() > 0) { + size_t waiting_time_samples = rtc::dchecked_cast( + buffer_.back().waiting_time->ElapsedMs() * (sample_rate / 1000)); + if (count_waiting_time) { + span += waiting_time_samples; + } else if (buffer_.back().frame && buffer_.back().frame->Duration() > 0) { size_t duration = buffer_.back().frame->Duration(); - if (count_dtx_waiting_time && buffer_.back().frame->IsDtxPacket()) { - size_t waiting_time_samples = rtc::dchecked_cast( - buffer_.back().waiting_time->ElapsedMs() * (sample_rate / 1000)); + if (buffer_.back().frame->IsDtxPacket()) { duration = std::max(duration, waiting_time_samples); } span += duration; diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.h b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.h index c6fb47ffbfdbf..1eef64a02cadc 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer.h @@ -150,7 +150,7 @@ class PacketBuffer { // across. virtual size_t GetSpanSamples(size_t last_decoded_length, size_t sample_rate, - bool count_dtx_waiting_time) const; + bool count_waiting_time) const; // Returns true if the packet buffer contains any DTX or CNG packets. virtual bool ContainsDtxOrCngPacket( diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer_unittest.cc index 1a054daca33a1..b0079645ff117 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/packet_buffer_unittest.cc @@ -134,7 +134,7 @@ TEST(PacketBuffer, InsertPacket) { EXPECT_FALSE(buffer.Empty()); EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); const Packet* next_packet = buffer.PeekNextPacket(); - EXPECT_EQ(packet, *next_packet); // Compare contents. + EXPECT_EQ(packet, *next_packet); // Compare contents. EXPECT_CALL(decoder_database, Die()); // Called when object is deleted. // Do not explicitly flush buffer or delete packet to test that it is deleted @@ -871,7 +871,7 @@ TEST(PacketBuffer, GetSpanSamples) { constexpr int kPayloadSizeBytes = 1; // Does not matter to this test; constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around. constexpr int kSampleRateHz = 48000; - constexpr bool KCountDtxWaitingTime = false; + constexpr bool kCountWaitingTime = false; TickTimer tick_timer; PacketBuffer buffer(3, &tick_timer); PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples); @@ -903,7 +903,7 @@ TEST(PacketBuffer, GetSpanSamples) { // input. EXPECT_EQ(kLastDecodedSizeSamples, buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz, - KCountDtxWaitingTime)); + kCountWaitingTime)); EXPECT_EQ(PacketBuffer::kOK, buffer.InsertPacket(/*packet=*/std::move(packet_2), @@ -914,13 +914,46 @@ TEST(PacketBuffer, GetSpanSamples) { /*decoder_database=*/decoder_database)); EXPECT_EQ(kFrameSizeSamples * 2, - buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime)); + buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime)); // packet_2 has access to duration, and ignores last decoded duration as // input. EXPECT_EQ(kFrameSizeSamples * 2, buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz, - KCountDtxWaitingTime)); + kCountWaitingTime)); +} + +TEST(PacketBuffer, GetSpanSamplesCountWaitingTime) { + constexpr size_t kFrameSizeSamples = 10; + constexpr int kPayloadSizeBytes = 1; // Does not matter to this test; + constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around. + constexpr int kSampleRateHz = 48000; + constexpr bool kCountWaitingTime = true; + constexpr size_t kLastDecodedSizeSamples = 0; + TickTimer tick_timer; + PacketBuffer buffer(3, &tick_timer); + PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples); + StrictMock mock_stats; + MockDecoderDatabase decoder_database; + + Packet packet = gen.NextPacket(kPayloadSizeBytes, nullptr); + + EXPECT_EQ(PacketBuffer::kOK, + buffer.InsertPacket(/*packet=*/std::move(packet), + /*stats=*/&mock_stats, + /*last_decoded_length=*/kFrameSizeSamples, + /*sample_rate=*/kSampleRateHz, + /*target_level_ms=*/60, + /*decoder_database=*/decoder_database)); + + EXPECT_EQ(0u, buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz, + kCountWaitingTime)); + + tick_timer.Increment(); + EXPECT_EQ(480u, buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime)); + + tick_timer.Increment(); + EXPECT_EQ(960u, buffer.GetSpanSamples(0, kSampleRateHz, kCountWaitingTime)); } namespace { diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/red_payload_splitter_unittest.cc b/third_party/libwebrtc/modules/audio_coding/neteq/red_payload_splitter_unittest.cc index a0ba5414ea44f..55f9bee272992 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/red_payload_splitter_unittest.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/red_payload_splitter_unittest.cc @@ -12,7 +12,6 @@ #include "modules/audio_coding/neteq/red_payload_splitter.h" - #include #include // pair diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.cc index 6c5e5ac2e439f..ad52239ae366a 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.cc @@ -21,47 +21,55 @@ namespace { class FakeEncodedFrame : public AudioDecoder::EncodedAudioFrame { public: - FakeEncodedFrame(AudioDecoder* decoder, rtc::Buffer&& payload) - : decoder_(decoder), payload_(std::move(payload)) {} + FakeEncodedFrame(FakeDecodeFromFile* decoder, + uint32_t timestamp, + size_t duration, + bool is_dtx) + : decoder_(decoder), + timestamp_(timestamp), + duration_(duration), + is_dtx_(is_dtx) {} - size_t Duration() const override { - const int ret = decoder_->PacketDuration(payload_.data(), payload_.size()); - return ret < 0 ? 0 : static_cast(ret); - } + size_t Duration() const override { return duration_; } absl::optional Decode( rtc::ArrayView decoded) const override { - auto speech_type = AudioDecoder::kSpeech; - const int ret = decoder_->Decode( - payload_.data(), payload_.size(), decoder_->SampleRateHz(), - decoded.size() * sizeof(int16_t), decoded.data(), &speech_type); - return ret < 0 ? absl::nullopt - : absl::optional( - {static_cast(ret), speech_type}); - } + if (is_dtx_) { + std::fill_n(decoded.data(), duration_, 0); + return DecodeResult{duration_, AudioDecoder::kComfortNoise}; + } - // This is to mimic OpusFrame. - bool IsDtxPacket() const override { - uint32_t original_payload_size_bytes = - ByteReader::ReadLittleEndian(&payload_.data()[8]); - return original_payload_size_bytes <= 2; + decoder_->ReadFromFile(timestamp_, duration_, decoded.data()); + return DecodeResult{Duration(), AudioDecoder::kSpeech}; } + bool IsDtxPacket() const override { return is_dtx_; } + private: - AudioDecoder* const decoder_; - const rtc::Buffer payload_; + FakeDecodeFromFile* const decoder_; + const uint32_t timestamp_; + const size_t duration_; + const bool is_dtx_; }; } // namespace -std::vector FakeDecodeFromFile::ParsePayload( - rtc::Buffer&& payload, - uint32_t timestamp) { - std::vector results; - std::unique_ptr frame( - new FakeEncodedFrame(this, std::move(payload))); - results.emplace_back(timestamp, 0, std::move(frame)); - return results; +void FakeDecodeFromFile::ReadFromFile(uint32_t timestamp, + size_t samples, + int16_t* destination) { + if (next_timestamp_from_input_ && timestamp != *next_timestamp_from_input_) { + // A gap in the timestamp sequence is detected. Skip the same number of + // samples from the file. + uint32_t jump = timestamp - *next_timestamp_from_input_; + RTC_CHECK(input_->Seek(jump)); + } + + next_timestamp_from_input_ = timestamp + samples; + RTC_CHECK(input_->Read(static_cast(samples), destination)); + + if (stereo_) { + InputAudioFile::DuplicateInterleaved(destination, samples, 2, destination); + } } int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, @@ -69,90 +77,18 @@ int FakeDecodeFromFile::DecodeInternal(const uint8_t* encoded, int sample_rate_hz, int16_t* decoded, SpeechType* speech_type) { + // This call is only used to produce codec-internal comfort noise. RTC_DCHECK_EQ(sample_rate_hz, SampleRateHz()); + RTC_DCHECK_EQ(encoded_len, 0); + RTC_DCHECK(!encoded); // NetEq always sends nullptr in this case. - const int samples_to_decode = PacketDuration(encoded, encoded_len); + const int samples_to_decode = rtc::CheckedDivExact(SampleRateHz(), 100); const int total_samples_to_decode = samples_to_decode * (stereo_ ? 2 : 1); - - if (encoded_len == 0) { - // Decoder is asked to produce codec-internal comfort noise. - RTC_DCHECK(!encoded); // NetEq always sends nullptr in this case. - RTC_DCHECK(cng_mode_); - RTC_DCHECK_GT(total_samples_to_decode, 0); - std::fill_n(decoded, total_samples_to_decode, 0); - *speech_type = kComfortNoise; - return rtc::dchecked_cast(total_samples_to_decode); - } - - RTC_CHECK_GE(encoded_len, 12); - uint32_t timestamp_to_decode = - ByteReader::ReadLittleEndian(encoded); - - if (next_timestamp_from_input_ && - timestamp_to_decode != *next_timestamp_from_input_) { - // A gap in the timestamp sequence is detected. Skip the same number of - // samples from the file. - uint32_t jump = timestamp_to_decode - *next_timestamp_from_input_; - RTC_CHECK(input_->Seek(jump)); - } - - next_timestamp_from_input_ = timestamp_to_decode + samples_to_decode; - - uint32_t original_payload_size_bytes = - ByteReader::ReadLittleEndian(&encoded[8]); - if (original_payload_size_bytes <= 2) { - // This is a comfort noise payload. - RTC_DCHECK_GT(total_samples_to_decode, 0); - std::fill_n(decoded, total_samples_to_decode, 0); - *speech_type = kComfortNoise; - cng_mode_ = true; - return rtc::dchecked_cast(total_samples_to_decode); - } - - cng_mode_ = false; - RTC_CHECK(input_->Read(static_cast(samples_to_decode), decoded)); - - if (stereo_) { - InputAudioFile::DuplicateInterleaved(decoded, samples_to_decode, 2, - decoded); - } - - *speech_type = kSpeech; - last_decoded_length_ = samples_to_decode; + std::fill_n(decoded, total_samples_to_decode, 0); + *speech_type = kComfortNoise; return rtc::dchecked_cast(total_samples_to_decode); } -int FakeDecodeFromFile::PacketDuration(const uint8_t* encoded, - size_t encoded_len) const { - const uint32_t original_payload_size_bytes = - encoded_len < 8 + sizeof(uint32_t) - ? 0 - : ByteReader::ReadLittleEndian(&encoded[8]); - const uint32_t samples_to_decode = - encoded_len < 4 + sizeof(uint32_t) - ? 0 - : ByteReader::ReadLittleEndian(&encoded[4]); - if (encoded_len == 0) { - // Decoder is asked to produce codec-internal comfort noise. - return rtc::CheckedDivExact(SampleRateHz(), 100); - } - bool is_dtx_payload = - original_payload_size_bytes <= 2 || samples_to_decode == 0; - bool has_error_duration = - samples_to_decode % rtc::CheckedDivExact(SampleRateHz(), 100) != 0; - if (is_dtx_payload || has_error_duration) { - if (last_decoded_length_ > 0) { - // Use length of last decoded packet. - return rtc::dchecked_cast(last_decoded_length_); - } else { - // This is the first packet to decode, and we do not know the length of - // it. Set it to 10 ms. - return rtc::CheckedDivExact(SampleRateHz(), 100); - } - } - return samples_to_decode; -} - void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp, size_t samples, size_t original_payload_size_bytes, @@ -165,5 +101,22 @@ void FakeDecodeFromFile::PrepareEncoded(uint32_t timestamp, &encoded[8], rtc::checked_cast(original_payload_size_bytes)); } +std::vector FakeDecodeFromFile::ParsePayload( + rtc::Buffer&& payload, + uint32_t timestamp) { + RTC_CHECK_GE(payload.size(), 12); + // Parse payload encoded in PrepareEncoded. + RTC_CHECK_EQ(timestamp, ByteReader::ReadLittleEndian(&payload[0])); + size_t samples = ByteReader::ReadLittleEndian(&payload[4]); + size_t original_payload_size_bytes = + ByteReader::ReadLittleEndian(&payload[8]); + bool opus_dtx = original_payload_size_bytes <= 2; + std::vector results; + results.emplace_back( + timestamp, 0, + std::make_unique(this, timestamp, samples, opus_dtx)); + return results; +} + } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.h index 7b53653998b76..050a29dc6553f 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/fake_decode_from_file.h @@ -52,7 +52,9 @@ class FakeDecodeFromFile : public AudioDecoder { int16_t* decoded, SpeechType* speech_type) override; - int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override; + // Reads `samples` from the input file and writes the results to + // `destination`. Location in file is determined by `timestamp`. + void ReadFromFile(uint32_t timestamp, size_t samples, int16_t* destination); // Helper method. Writes `timestamp`, `samples` and // `original_payload_size_bytes` to `encoded` in a format that the @@ -68,8 +70,6 @@ class FakeDecodeFromFile : public AudioDecoder { absl::optional next_timestamp_from_input_; const int sample_rate_hz_; const bool stereo_; - size_t last_decoded_length_ = 0; - bool cng_mode_ = false; }; } // namespace test diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.cc index 26255b7771a68..0ca855b62686e 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.cc @@ -14,64 +14,153 @@ #include #include "absl/strings/string_view.h" -#include "modules/audio_coding/neteq/tools/rtc_event_log_source.h" #include "rtc_base/checks.h" namespace webrtc { namespace test { +namespace { -NetEqEventLogInput* NetEqEventLogInput::CreateFromFile( - absl::string_view file_name, - absl::optional ssrc_filter) { - auto event_log_src = - RtcEventLogSource::CreateFromFile(file_name, ssrc_filter); - if (!event_log_src) { - return nullptr; +class NetEqEventLogInput : public NetEqInput { + public: + NetEqEventLogInput(const std::vector& packet_stream, + const std::vector& output_events, + const std::vector& + neteq_set_minimum_delay_events, + absl::optional end_time_ms) + : packet_stream_(packet_stream), + packet_stream_it_(packet_stream_.begin()), + output_events_(output_events), + output_events_it_(output_events_.begin()), + neteq_set_minimum_delay_events_(neteq_set_minimum_delay_events), + neteq_set_minimum_delay_events_it_( + neteq_set_minimum_delay_events_.begin()), + end_time_ms_(end_time_ms) { + // Ignore all output events before the first packet. + while (output_events_it_ != output_events_.end() && + output_events_it_->log_time_ms() < + packet_stream_it_->log_time_ms()) { + ++output_events_it_; + } } - return new NetEqEventLogInput(std::move(event_log_src)); -} -NetEqEventLogInput* NetEqEventLogInput::CreateFromString( - absl::string_view file_contents, - absl::optional ssrc_filter) { - auto event_log_src = - RtcEventLogSource::CreateFromString(file_contents, ssrc_filter); - if (!event_log_src) { - return nullptr; + absl::optional NextPacketTime() const override { + if (packet_stream_it_ == packet_stream_.end()) { + return absl::nullopt; + } + if (end_time_ms_ && packet_stream_it_->rtp.log_time_ms() > *end_time_ms_) { + return absl::nullopt; + } + return packet_stream_it_->rtp.log_time_ms(); } - return new NetEqEventLogInput(std::move(event_log_src)); -} -absl::optional NetEqEventLogInput::NextOutputEventTime() const { - return next_output_event_ms_; -} + absl::optional NextOutputEventTime() const override { + if (output_events_it_ == output_events_.end()) { + return absl::nullopt; + } + if (end_time_ms_ && output_events_it_->log_time_ms() > *end_time_ms_) { + return absl::nullopt; + } + return output_events_it_->log_time_ms(); + } -absl::optional -NetEqEventLogInput::NextSetMinimumDelayInfo() const { - return next_minimum_delay_event_info_; -} + absl::optional NextSetMinimumDelayInfo() const override { + if (neteq_set_minimum_delay_events_it_ == + neteq_set_minimum_delay_events_.end()) { + return absl::nullopt; + } + if (end_time_ms_ && + neteq_set_minimum_delay_events_it_->log_time_ms() > *end_time_ms_) { + return absl::nullopt; + } + return SetMinimumDelayInfo( + neteq_set_minimum_delay_events_it_->log_time_ms(), + neteq_set_minimum_delay_events_it_->minimum_delay_ms); + } + + std::unique_ptr PopPacket() override { + if (packet_stream_it_ == packet_stream_.end()) { + return nullptr; + } + auto packet_data = std::make_unique(); + packet_data->header = packet_stream_it_->rtp.header; + packet_data->time_ms = packet_stream_it_->rtp.log_time_ms(); -void NetEqEventLogInput::AdvanceOutputEvent() { - next_output_event_ms_ = source_->NextAudioOutputEventMs(); - if (*next_output_event_ms_ == std::numeric_limits::max()) { - next_output_event_ms_ = absl::nullopt; + // This is a header-only "dummy" packet. Set the payload to all zeros, with + // length according to the virtual length. + packet_data->payload.SetSize(packet_stream_it_->rtp.total_length - + packet_stream_it_->rtp.header_length); + std::fill_n(packet_data->payload.data(), packet_data->payload.size(), 0); + + ++packet_stream_it_; + return packet_data; } -} -void NetEqEventLogInput::AdvanceSetMinimumDelay() { - next_minimum_delay_event_info_ = source_->NextSetMinimumDelayEvent(); -} + void AdvanceOutputEvent() override { + if (output_events_it_ != output_events_.end()) { + ++output_events_it_; + } + } -PacketSource* NetEqEventLogInput::source() { - return source_.get(); -} + void AdvanceSetMinimumDelay() override { + if (neteq_set_minimum_delay_events_it_ != + neteq_set_minimum_delay_events_.end()) { + ++neteq_set_minimum_delay_events_it_; + } + } + + bool ended() const override { return !NextEventTime(); } + + absl::optional NextHeader() const override { + if (packet_stream_it_ == packet_stream_.end()) { + return absl::nullopt; + } + return packet_stream_it_->rtp.header; + } -NetEqEventLogInput::NetEqEventLogInput( - std::unique_ptr source) - : source_(std::move(source)) { - LoadNextPacket(); - AdvanceOutputEvent(); - AdvanceSetMinimumDelay(); + private: + const std::vector packet_stream_; + std::vector::const_iterator packet_stream_it_; + const std::vector output_events_; + std::vector::const_iterator output_events_it_; + const std::vector + neteq_set_minimum_delay_events_; + std::vector::const_iterator + neteq_set_minimum_delay_events_it_; + const absl::optional end_time_ms_; +}; + +} // namespace + +std::unique_ptr CreateNetEqEventLogInput( + const ParsedRtcEventLog& parsed_log, + absl::optional ssrc) { + if (parsed_log.incoming_audio_ssrcs().empty()) { + return nullptr; + } + // Pick the first SSRC if none was provided. + ssrc = ssrc.value_or(*parsed_log.incoming_audio_ssrcs().begin()); + auto streams = parsed_log.incoming_rtp_packets_by_ssrc(); + auto stream = + std::find_if(streams.begin(), streams.end(), + [ssrc](auto stream) { return stream.ssrc == ssrc; }); + if (stream == streams.end()) { + return nullptr; + } + auto output_events_it = parsed_log.audio_playout_events().find(*ssrc); + if (output_events_it == parsed_log.audio_playout_events().end()) { + return nullptr; + } + std::vector neteq_set_minimum_delay_events; + auto neteq_set_minimum_delay_events_it = + parsed_log.neteq_set_minimum_delay_events().find(*ssrc); + if (neteq_set_minimum_delay_events_it != + parsed_log.neteq_set_minimum_delay_events().end()) { + neteq_set_minimum_delay_events = neteq_set_minimum_delay_events_it->second; + } + int64_t end_time_ms = parsed_log.first_log_segment().stop_time_ms(); + return std::make_unique( + stream->incoming_packets, output_events_it->second, + neteq_set_minimum_delay_events, end_time_ms); } } // namespace test diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.h index 1e64cc59a44db..a84de8469c264 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_event_log_input.h @@ -11,43 +11,17 @@ #ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EVENT_LOG_INPUT_H_ #define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EVENT_LOG_INPUT_H_ -#include -#include -#include - #include "absl/strings/string_view.h" -#include "modules/audio_coding/neteq/tools/neteq_packet_source_input.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "absl/types/optional.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "modules/audio_coding/neteq/tools/neteq_input.h" namespace webrtc { namespace test { -class RtcEventLogSource; - -// Implementation of NetEqPacketSourceInput to be used with an -// RtcEventLogSource. -class NetEqEventLogInput final : public NetEqPacketSourceInput { - public: - static NetEqEventLogInput* CreateFromFile( - absl::string_view file_name, - absl::optional ssrc_filter); - static NetEqEventLogInput* CreateFromString( - absl::string_view file_contents, - absl::optional ssrc_filter); - - absl::optional NextOutputEventTime() const override; - absl::optional NextSetMinimumDelayInfo() const override; - void AdvanceOutputEvent() override; - void AdvanceSetMinimumDelay() override; - - protected: - PacketSource* source() override; - - private: - NetEqEventLogInput(std::unique_ptr source); - std::unique_ptr source_; - absl::optional next_minimum_delay_event_info_; -}; +std::unique_ptr CreateNetEqEventLogInput( + const ParsedRtcEventLog& parsed_log, + absl::optional ssrc); } // namespace test } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc deleted file mode 100644 index 55a56532381e0..0000000000000 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016 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/tools/neteq_packet_source_input.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "modules/audio_coding/neteq/tools/rtp_file_source.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace test { - -NetEqPacketSourceInput::NetEqPacketSourceInput() : next_output_event_ms_(0) {} - -absl::optional NetEqPacketSourceInput::NextPacketTime() const { - return packet_ - ? absl::optional(static_cast(packet_->time_ms())) - : absl::nullopt; -} - -absl::optional NetEqPacketSourceInput::NextHeader() const { - return packet_ ? absl::optional(packet_->header()) : absl::nullopt; -} - -void NetEqPacketSourceInput::LoadNextPacket() { - packet_ = source()->NextPacket(); -} - -std::unique_ptr NetEqPacketSourceInput::PopPacket() { - if (!packet_) { - return std::unique_ptr(); - } - std::unique_ptr packet_data(new PacketData); - packet_data->header = packet_->header(); - if (packet_->payload_length_bytes() == 0 && - packet_->virtual_payload_length_bytes() > 0) { - // This is a header-only "dummy" packet. Set the payload to all zeros, with - // length according to the virtual length. - packet_data->payload.SetSize(packet_->virtual_payload_length_bytes()); - std::fill_n(packet_data->payload.data(), packet_data->payload.size(), 0); - } else { - packet_data->payload.SetData(packet_->payload(), - packet_->payload_length_bytes()); - } - packet_data->time_ms = packet_->time_ms(); - - LoadNextPacket(); - - return packet_data; -} - -NetEqRtpDumpInput::NetEqRtpDumpInput(absl::string_view file_name, - const RtpHeaderExtensionMap& hdr_ext_map, - absl::optional ssrc_filter) - : source_(RtpFileSource::Create(file_name, ssrc_filter)) { - for (const auto& ext_pair : hdr_ext_map) { - source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first); - } - LoadNextPacket(); -} - -absl::optional NetEqRtpDumpInput::NextOutputEventTime() const { - return next_output_event_ms_; -} - -void NetEqRtpDumpInput::AdvanceOutputEvent() { - if (next_output_event_ms_) { - *next_output_event_ms_ += kOutputPeriodMs; - } - if (!NextPacketTime()) { - next_output_event_ms_ = absl::nullopt; - } -} - -PacketSource* NetEqRtpDumpInput::source() { - return source_.get(); -} - -} // namespace test -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.h deleted file mode 100644 index 1b48b1f8cf84f..0000000000000 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_packet_source_input.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016 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_TOOLS_NETEQ_PACKET_SOURCE_INPUT_H_ -#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PACKET_SOURCE_INPUT_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "modules/audio_coding/neteq/tools/neteq_input.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" - -namespace webrtc { -namespace test { - -class RtpFileSource; - -// An adapter class to dress up a PacketSource object as a NetEqInput. -class NetEqPacketSourceInput : public NetEqInput { - public: - using RtpHeaderExtensionMap = std::map; - - NetEqPacketSourceInput(); - absl::optional NextPacketTime() const override; - std::unique_ptr PopPacket() override; - absl::optional NextHeader() const override; - bool ended() const override { return !next_output_event_ms_; } - - protected: - virtual PacketSource* source() = 0; - void LoadNextPacket(); - - absl::optional next_output_event_ms_; - - private: - std::unique_ptr packet_; -}; - -// Implementation of NetEqPacketSourceInput to be used with an RtpFileSource. -class NetEqRtpDumpInput final : public NetEqPacketSourceInput { - public: - NetEqRtpDumpInput(absl::string_view file_name, - const RtpHeaderExtensionMap& hdr_ext_map, - absl::optional ssrc_filter); - - absl::optional NextOutputEventTime() const override; - absl::optional NextSetMinimumDelayInfo() const override { - return absl::nullopt; - } - void AdvanceOutputEvent() override; - void AdvanceSetMinimumDelay() override {} - - protected: - PacketSource* source() override; - - private: - static constexpr int64_t kOutputPeriodMs = 10; - - std::unique_ptr source_; -}; - -} // namespace test -} // namespace webrtc -#endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PACKET_SOURCE_INPUT_H_ diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_replacement_input.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_replacement_input.cc index 9436b68ac9fab..081bd9631f596 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_replacement_input.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_replacement_input.cc @@ -105,8 +105,9 @@ void NetEqReplacementInput::ReplacePacket() { uint32_t input_frame_size_timestamps = last_frame_size_timestamps_; const uint32_t timestamp_diff = 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) { + timestamp_diff <= 120 * 48 && !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; diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc new file mode 100644 index 0000000000000..20e092b079245 --- /dev/null +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.cc @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016 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/tools/neteq_rtp_dump_input.h" + +#include "absl/strings/string_view.h" +#include "modules/audio_coding/neteq/tools/rtp_file_source.h" + +namespace webrtc { +namespace test { +namespace { + +// An adapter class to dress up a PacketSource object as a NetEqInput. +class NetEqRtpDumpInput : public NetEqInput { + public: + NetEqRtpDumpInput(absl::string_view file_name, + const std::map& hdr_ext_map, + absl::optional ssrc_filter) + : source_(RtpFileSource::Create(file_name, ssrc_filter)) { + for (const auto& ext_pair : hdr_ext_map) { + source_->RegisterRtpHeaderExtension(ext_pair.second, ext_pair.first); + } + LoadNextPacket(); + } + + absl::optional NextOutputEventTime() const override { + return next_output_event_ms_; + } + + absl::optional NextSetMinimumDelayInfo() const override { + return absl::nullopt; + } + + void AdvanceOutputEvent() override { + if (next_output_event_ms_) { + *next_output_event_ms_ += kOutputPeriodMs; + } + if (!NextPacketTime()) { + next_output_event_ms_ = absl::nullopt; + } + } + + void AdvanceSetMinimumDelay() override {} + + absl::optional NextPacketTime() const override { + return packet_ ? absl::optional( + static_cast(packet_->time_ms())) + : absl::nullopt; + } + + std::unique_ptr PopPacket() override { + if (!packet_) { + return std::unique_ptr(); + } + std::unique_ptr packet_data(new PacketData); + packet_data->header = packet_->header(); + if (packet_->payload_length_bytes() == 0 && + packet_->virtual_payload_length_bytes() > 0) { + // This is a header-only "dummy" packet. Set the payload to all zeros, + // with length according to the virtual length. + packet_data->payload.SetSize(packet_->virtual_payload_length_bytes()); + std::fill_n(packet_data->payload.data(), packet_data->payload.size(), 0); + } else { + packet_data->payload.SetData(packet_->payload(), + packet_->payload_length_bytes()); + } + packet_data->time_ms = packet_->time_ms(); + + LoadNextPacket(); + + return packet_data; + } + + absl::optional NextHeader() const override { + return packet_ ? absl::optional(packet_->header()) + : absl::nullopt; + } + + bool ended() const override { return !next_output_event_ms_; } + + private: + void LoadNextPacket() { packet_ = source_->NextPacket(); } + + absl::optional next_output_event_ms_ = 0; + static constexpr int64_t kOutputPeriodMs = 10; + + std::unique_ptr source_; + std::unique_ptr packet_; +}; + +} // namespace + +std::unique_ptr CreateNetEqRtpDumpInput( + absl::string_view file_name, + const std::map& hdr_ext_map, + absl::optional ssrc_filter) { + return std::make_unique(file_name, hdr_ext_map, + ssrc_filter); +} + +} // namespace test +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h new file mode 100644 index 0000000000000..e68ebb2c2c5ca --- /dev/null +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016 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_TOOLS_NETEQ_RTP_DUMP_INPUT_H_ +#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_RTP_DUMP_INPUT_H_ + +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "modules/audio_coding/neteq/tools/neteq_input.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" + +namespace webrtc { +namespace test { + +std::unique_ptr CreateNetEqRtpDumpInput( + absl::string_view file_name, + const std::map& hdr_ext_map, + absl::optional ssrc_filter); + +} // namespace test +} // namespace webrtc +#endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_RTP_DUMP_INPUT_H_ diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test.cc index 125d087157ba0..82dd0ae1c1cd9 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test.cc @@ -313,30 +313,28 @@ NetEqLifetimeStatistics NetEqTest::LifetimeStats() const { } NetEqTest::DecoderMap NetEqTest::StandardDecoderMap() { - DecoderMap codecs = { - {0, SdpAudioFormat("pcmu", 8000, 1)}, - {8, SdpAudioFormat("pcma", 8000, 1)}, + DecoderMap codecs = {{0, SdpAudioFormat("pcmu", 8000, 1)}, + {8, SdpAudioFormat("pcma", 8000, 1)}, #ifdef WEBRTC_CODEC_ILBC - {102, SdpAudioFormat("ilbc", 8000, 1)}, + {102, SdpAudioFormat("ilbc", 8000, 1)}, #endif #ifdef WEBRTC_CODEC_OPUS - {111, SdpAudioFormat("opus", 48000, 2)}, + {111, SdpAudioFormat("opus", 48000, 2)}, #endif - {93, SdpAudioFormat("l16", 8000, 1)}, - {94, SdpAudioFormat("l16", 16000, 1)}, - {95, SdpAudioFormat("l16", 32000, 1)}, - {96, SdpAudioFormat("l16", 48000, 1)}, - {9, SdpAudioFormat("g722", 8000, 1)}, - {106, SdpAudioFormat("telephone-event", 8000, 1)}, - {114, SdpAudioFormat("telephone-event", 16000, 1)}, - {115, SdpAudioFormat("telephone-event", 32000, 1)}, - {116, SdpAudioFormat("telephone-event", 48000, 1)}, - {117, SdpAudioFormat("red", 8000, 1)}, - {13, SdpAudioFormat("cn", 8000, 1)}, - {98, SdpAudioFormat("cn", 16000, 1)}, - {99, SdpAudioFormat("cn", 32000, 1)}, - {100, SdpAudioFormat("cn", 48000, 1)} - }; + {93, SdpAudioFormat("l16", 8000, 1)}, + {94, SdpAudioFormat("l16", 16000, 1)}, + {95, SdpAudioFormat("l16", 32000, 1)}, + {96, SdpAudioFormat("l16", 48000, 1)}, + {9, SdpAudioFormat("g722", 8000, 1)}, + {106, SdpAudioFormat("telephone-event", 8000, 1)}, + {114, SdpAudioFormat("telephone-event", 16000, 1)}, + {115, SdpAudioFormat("telephone-event", 32000, 1)}, + {116, SdpAudioFormat("telephone-event", 48000, 1)}, + {117, SdpAudioFormat("red", 8000, 1)}, + {13, SdpAudioFormat("cn", 8000, 1)}, + {98, SdpAudioFormat("cn", 16000, 1)}, + {99, SdpAudioFormat("cn", 32000, 1)}, + {100, SdpAudioFormat("cn", 48000, 1)}}; return codecs; } diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test_factory.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test_factory.cc index 6cd371406c816..981504b23908a 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test_factory.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/neteq_test_factory.cc @@ -31,8 +31,8 @@ #include "modules/audio_coding/neteq/tools/input_audio_file.h" #include "modules/audio_coding/neteq/tools/neteq_delay_analyzer.h" #include "modules/audio_coding/neteq/tools/neteq_event_log_input.h" -#include "modules/audio_coding/neteq/tools/neteq_packet_source_input.h" #include "modules/audio_coding/neteq/tools/neteq_replacement_input.h" +#include "modules/audio_coding/neteq/tools/neteq_rtp_dump_input.h" #include "modules/audio_coding/neteq/tools/neteq_stats_getter.h" #include "modules/audio_coding/neteq/tools/neteq_stats_plotter.h" #include "modules/audio_coding/neteq/tools/neteq_test.h" @@ -112,8 +112,14 @@ std::unique_ptr NetEqTestFactory::InitializeTestFromString( absl::string_view input_string, NetEqFactory* factory, const Config& config) { - std::unique_ptr input( - NetEqEventLogInput::CreateFromString(input_string, config.ssrc_filter)); + ParsedRtcEventLog parsed_log; + auto status = parsed_log.ParseString(input_string); + if (!status.ok()) { + std::cerr << "Failed to parse event log: " << status.message() << std::endl; + return nullptr; + } + std::unique_ptr input = + CreateNetEqEventLogInput(parsed_log, config.ssrc_filter); if (!input) { std::cerr << "Error: Cannot parse input string" << std::endl; return nullptr; @@ -126,7 +132,7 @@ std::unique_ptr NetEqTestFactory::InitializeTestFromFile( NetEqFactory* factory, const Config& config) { // Gather RTP header extensions in a map. - NetEqPacketSourceInput::RtpHeaderExtensionMap rtp_ext_map = { + std::map rtp_ext_map = { {config.audio_level, kRtpExtensionAudioLevel}, {config.abs_send_time, kRtpExtensionAbsoluteSendTime}, {config.transport_seq_no, kRtpExtensionTransportSequenceNumber}, @@ -136,11 +142,17 @@ std::unique_ptr NetEqTestFactory::InitializeTestFromFile( std::unique_ptr input; if (RtpFileSource::ValidRtpDump(input_file_name) || RtpFileSource::ValidPcap(input_file_name)) { - input.reset(new NetEqRtpDumpInput(input_file_name, rtp_ext_map, - config.ssrc_filter)); + input = CreateNetEqRtpDumpInput(input_file_name, rtp_ext_map, + config.ssrc_filter); } else { - input.reset(NetEqEventLogInput::CreateFromFile(input_file_name, - config.ssrc_filter)); + ParsedRtcEventLog parsed_log; + auto status = parsed_log.ParseFile(input_file_name); + if (!status.ok()) { + std::cerr << "Failed to parse event log: " << status.message() + << std::endl; + return nullptr; + } + input = CreateNetEqEventLogInput(parsed_log, config.ssrc_filter); } std::cout << "Input file: " << input_file_name << std::endl; diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/packet.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/packet.h index 96710907dfd78..a4b3da9a4bdc5 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/packet.h +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/packet.h @@ -95,7 +95,7 @@ class Packet { // Virtual lengths are used when parsing RTP header files (dummy RTP files). const size_t virtual_packet_length_bytes_; size_t virtual_payload_length_bytes_ = 0; - const double time_ms_; // Used to denote a packet's arrival time. + const double time_ms_; // Used to denote a packet's arrival time. const bool valid_header_; }; diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc deleted file mode 100644 index 68acfb7f6229f..0000000000000 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2015 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/tools/rtc_event_log_source.h" - -#include - -#include -#include -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "logging/rtc_event_log/rtc_event_processor.h" -#include "modules/audio_coding/neteq/tools/neteq_input.h" -#include "modules/audio_coding/neteq/tools/packet.h" -#include "rtc_base/checks.h" - -namespace webrtc { -namespace test { - -namespace { -bool ShouldSkipStream(ParsedRtcEventLog::MediaType media_type, - uint32_t ssrc, - absl::optional ssrc_filter) { - if (media_type != ParsedRtcEventLog::MediaType::AUDIO) - return true; - if (ssrc_filter.has_value() && ssrc != *ssrc_filter) - return true; - return false; -} -} // namespace - -std::unique_ptr RtcEventLogSource::CreateFromFile( - absl::string_view file_name, - absl::optional ssrc_filter) { - auto source = std::unique_ptr(new RtcEventLogSource()); - ParsedRtcEventLog parsed_log; - auto status = parsed_log.ParseFile(file_name); - if (!status.ok()) { - std::cerr << "Failed to parse event log: " << status.message() << std::endl; - std::cerr << "Skipping log." << std::endl; - return nullptr; - } - if (!source->Initialize(parsed_log, ssrc_filter)) { - std::cerr << "Failed to initialize source from event log, skipping." - << std::endl; - return nullptr; - } - return source; -} - -std::unique_ptr RtcEventLogSource::CreateFromString( - absl::string_view file_contents, - absl::optional ssrc_filter) { - auto source = std::unique_ptr(new RtcEventLogSource()); - ParsedRtcEventLog parsed_log; - auto status = parsed_log.ParseString(file_contents); - if (!status.ok()) { - std::cerr << "Failed to parse event log: " << status.message() << std::endl; - std::cerr << "Skipping log." << std::endl; - return nullptr; - } - if (!source->Initialize(parsed_log, ssrc_filter)) { - std::cerr << "Failed to initialize source from event log, skipping." - << std::endl; - return nullptr; - } - return source; -} - -RtcEventLogSource::~RtcEventLogSource() {} - -std::unique_ptr RtcEventLogSource::NextPacket() { - if (rtp_packet_index_ >= rtp_packets_.size()) - return nullptr; - - std::unique_ptr packet = std::move(rtp_packets_[rtp_packet_index_++]); - return packet; -} - -int64_t RtcEventLogSource::NextAudioOutputEventMs() { - if (audio_output_index_ >= audio_outputs_.size()) - return std::numeric_limits::max(); - - int64_t output_time_ms = audio_outputs_[audio_output_index_++]; - return output_time_ms; -} - -absl::optional -RtcEventLogSource::NextSetMinimumDelayEvent() { - if (minimum_delay_index_ >= minimum_delay_.size()) { - return absl::nullopt; - } - return minimum_delay_[minimum_delay_index_++]; -} - -RtcEventLogSource::RtcEventLogSource() : PacketSource() {} - -bool RtcEventLogSource::Initialize(const ParsedRtcEventLog& parsed_log, - absl::optional ssrc_filter) { - const auto first_log_end_time_us = - parsed_log.stop_log_events().empty() - ? std::numeric_limits::max() - : parsed_log.stop_log_events().front().log_time_us(); - - std::set packet_ssrcs; - auto handle_rtp_packet = - [this, first_log_end_time_us, - &packet_ssrcs](const webrtc::LoggedRtpPacketIncoming& incoming) { - if (!filter_.test(incoming.rtp.header.payloadType) && - incoming.log_time_us() < first_log_end_time_us) { - rtp_packets_.emplace_back(std::make_unique( - incoming.rtp.header, incoming.rtp.total_length, - incoming.rtp.total_length - incoming.rtp.header_length, - static_cast(incoming.log_time_ms()))); - packet_ssrcs.insert(rtp_packets_.back()->header().ssrc); - } - }; - - std::set ignored_ssrcs; - auto handle_audio_playout = - [this, first_log_end_time_us, &packet_ssrcs, - &ignored_ssrcs](const webrtc::LoggedAudioPlayoutEvent& audio_playout) { - if (audio_playout.log_time_us() < first_log_end_time_us) { - if (packet_ssrcs.count(audio_playout.ssrc) > 0) { - audio_outputs_.emplace_back(audio_playout.log_time_ms()); - } else { - ignored_ssrcs.insert(audio_playout.ssrc); - } - } - }; - - auto handle_neteq_set_minimum_delay = - [this, first_log_end_time_us, &packet_ssrcs]( - const webrtc::LoggedNetEqSetMinimumDelayEvent minimum_delay_event) { - if (minimum_delay_event.log_time_us() < first_log_end_time_us) { - if (packet_ssrcs.count(minimum_delay_event.remote_ssrc) > 0) { - minimum_delay_.emplace_back(minimum_delay_event.log_time_ms(), - minimum_delay_event.minimum_delay_ms); - } - } - }; - - // This wouldn't be needed if we knew that there was at most one audio stream. - webrtc::RtcEventProcessor event_processor; - for (const auto& rtp_packets : parsed_log.incoming_rtp_packets_by_ssrc()) { - ParsedRtcEventLog::MediaType media_type = - parsed_log.GetMediaType(rtp_packets.ssrc, webrtc::kIncomingPacket); - if (ShouldSkipStream(media_type, rtp_packets.ssrc, ssrc_filter)) { - continue; - } - event_processor.AddEvents(rtp_packets.incoming_packets, handle_rtp_packet); - // If no SSRC filter has been set, use the first SSRC only. The simulator - // does not work properly with interleaved packets from multiple SSRCs. - if (!ssrc_filter.has_value()) { - ssrc_filter = rtp_packets.ssrc; - } - } - - for (const auto& audio_playouts : parsed_log.audio_playout_events()) { - if (ssrc_filter.has_value() && audio_playouts.first != *ssrc_filter) - continue; - event_processor.AddEvents(audio_playouts.second, handle_audio_playout); - } - - for (const auto& neteq_set_minimum_delay_event : - parsed_log.neteq_set_minimum_delay_events()) { - if (ssrc_filter.has_value() && - neteq_set_minimum_delay_event.first != *ssrc_filter) { - continue; - } - event_processor.AddEvents(neteq_set_minimum_delay_event.second, - handle_neteq_set_minimum_delay); - } - - // Fills in rtp_packets_ and audio_outputs_. - event_processor.ProcessEventsInOrder(); - - for (const auto& ssrc : ignored_ssrcs) { - std::cout << "Ignoring GetAudio events from SSRC 0x" << std::hex << ssrc - << " because no packets were found with a matching SSRC." - << std::endl; - } - - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h deleted file mode 100644 index 1445314247c30..0000000000000 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015 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_TOOLS_RTC_EVENT_LOG_SOURCE_H_ -#define MODULES_AUDIO_CODING_NETEQ_TOOLS_RTC_EVENT_LOG_SOURCE_H_ - -#include -#include -#include - -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" -#include "logging/rtc_event_log/rtc_event_log_parser.h" -#include "modules/audio_coding/neteq/tools/neteq_input.h" -#include "modules/audio_coding/neteq/tools/packet_source.h" -#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" - -namespace webrtc { - -class RtpHeaderParser; - -namespace test { - -class Packet; - -class RtcEventLogSource : public PacketSource { - public: - // Creates an RtcEventLogSource reading from `file_name`. If the file cannot - // be opened, or has the wrong format, NULL will be returned. - static std::unique_ptr CreateFromFile( - absl::string_view file_name, - absl::optional ssrc_filter); - // Same as above, but uses a string with the file contents. - static std::unique_ptr CreateFromString( - absl::string_view file_contents, - absl::optional ssrc_filter); - - virtual ~RtcEventLogSource(); - - RtcEventLogSource(const RtcEventLogSource&) = delete; - RtcEventLogSource& operator=(const RtcEventLogSource&) = delete; - - std::unique_ptr NextPacket() override; - - // Returns the timestamp of the next audio output event, in milliseconds. The - // maximum value of int64_t is returned if there are no more audio output - // events available. - int64_t NextAudioOutputEventMs(); - - // Returns the next NetEq set minimum delay event if available. - absl::optional NextSetMinimumDelayEvent(); - - private: - RtcEventLogSource(); - - bool Initialize(const ParsedRtcEventLog& parsed_log, - absl::optional ssrc_filter); - - std::vector> rtp_packets_; - size_t rtp_packet_index_ = 0; - std::vector audio_outputs_; - size_t audio_output_index_ = 0; - std::vector minimum_delay_; - size_t minimum_delay_index_ = 0; -}; - -} // namespace test -} // namespace webrtc - -#endif // MODULES_AUDIO_CODING_NETEQ_TOOLS_RTC_EVENT_LOG_SOURCE_H_ diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc index a43c29638cefb..7a8daef945b67 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc @@ -80,8 +80,7 @@ std::unique_ptr RtpFileSource::NextPacket() { } RtpFileSource::RtpFileSource(absl::optional ssrc_filter) - : PacketSource(), - ssrc_filter_(ssrc_filter) {} + : PacketSource(), ssrc_filter_(ssrc_filter) {} bool RtpFileSource::OpenFile(absl::string_view file_name) { rtp_reader_.reset(RtpFileReader::Create(RtpFileReader::kRtpDump, file_name)); diff --git a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_generator.cc b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_generator.cc index e883fc11d62a2..5633f11b86347 100644 --- a/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_generator.cc +++ b/third_party/libwebrtc/modules/audio_coding/neteq/tools/rtp_generator.cc @@ -10,7 +10,6 @@ #include "modules/audio_coding/neteq/tools/rtp_generator.h" - namespace webrtc { namespace test { diff --git a/third_party/libwebrtc/modules/audio_coding/test/EncodeDecodeTest.cc b/third_party/libwebrtc/modules/audio_coding/test/EncodeDecodeTest.cc index 014a1d2d54613..cab36458e0e97 100644 --- a/third_party/libwebrtc/modules/audio_coding/test/EncodeDecodeTest.cc +++ b/third_party/libwebrtc/modules/audio_coding/test/EncodeDecodeTest.cc @@ -229,8 +229,8 @@ EncodeDecodeTest::EncodeDecodeTest() = default; void EncodeDecodeTest::Perform() { const std::map send_codecs = { - {107, {"L16", 8000, 1}}, {108, {"L16", 16000, 1}}, - {109, {"L16", 32000, 1}}, {0, {"PCMU", 8000, 1}}, + {107, {"L16", 8000, 1}}, {108, {"L16", 16000, 1}}, + {109, {"L16", 32000, 1}}, {0, {"PCMU", 8000, 1}}, {8, {"PCMA", 8000, 1}}, #ifdef WEBRTC_CODEC_ILBC {102, {"ILBC", 8000, 1}}, diff --git a/third_party/libwebrtc/modules/audio_device/BUILD.gn b/third_party/libwebrtc/modules/audio_device/BUILD.gn index 61cd531edd62b..ab8ec28ba2452 100644 --- a/third_party/libwebrtc/modules/audio_device/BUILD.gn +++ b/third_party/libwebrtc/modules/audio_device/BUILD.gn @@ -181,6 +181,36 @@ rtc_source_set("audio_device_module_from_input_and_output") { } } +rtc_library("test_audio_device_module") { + visibility = [ "*" ] + sources = [ + "include/test_audio_device.cc", + "include/test_audio_device.h", + ] + deps = [ + ":audio_device_api", + ":audio_device_default", + "../../api:array_view", + "../../api:make_ref_counted", + "../../api:scoped_refptr", + "../../api/task_queue", + "../../common_audio", + "../../rtc_base:buffer", + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../rtc_base:macromagic", + "../../rtc_base:platform_thread", + "../../rtc_base:random", + "../../rtc_base:rtc_event", + "../../rtc_base:rtc_task_queue", + "../../rtc_base:safe_conversions", + "../../rtc_base:timeutils", + "../../rtc_base/synchronization:mutex", + "../../rtc_base/task_utils:repeating_task", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] +} + # Contains default implementations of webrtc::AudioDeviceModule for Windows, # Linux, Mac, iOS and Android. rtc_library("audio_device_impl") { @@ -233,8 +263,6 @@ if (!build_with_mozilla) { # See Bug 1820869. "dummy/file_audio_device.cc", "dummy/file_audio_device.h", "include/fake_audio_device.h", - "include/test_audio_device.cc", - "include/test_audio_device.h", ] if (build_with_mozilla) { @@ -429,6 +457,7 @@ if (rtc_include_tests && !build_with_chromium && !build_with_mozilla) { ":audio_device_buffer", ":audio_device_impl", ":mock_audio_device", + ":test_audio_device_module", "../../api:array_view", "../../api:scoped_refptr", "../../api:sequence_checker", diff --git a/third_party/libwebrtc/modules/audio_device/include/test_audio_device.cc b/third_party/libwebrtc/modules/audio_device/include/test_audio_device.cc index eacded7728d64..76406448a085c 100644 --- a/third_party/libwebrtc/modules/audio_device/include/test_audio_device.cc +++ b/third_party/libwebrtc/modules/audio_device/include/test_audio_device.cc @@ -439,7 +439,7 @@ size_t TestAudioDeviceModule::SamplesPerFrame(int sampling_frequency_in_hz) { return rtc::CheckedDivExact(sampling_frequency_in_hz, kFramesPerSecond); } -rtc::scoped_refptr TestAudioDeviceModule::Create( +rtc::scoped_refptr TestAudioDeviceModule::Create( TaskQueueFactory* task_queue_factory, std::unique_ptr capturer, std::unique_ptr renderer, diff --git a/third_party/libwebrtc/modules/audio_device/include/test_audio_device.h b/third_party/libwebrtc/modules/audio_device/include/test_audio_device.h index 8413479291b0a..87ba9cfbae79f 100644 --- a/third_party/libwebrtc/modules/audio_device/include/test_audio_device.h +++ b/third_party/libwebrtc/modules/audio_device/include/test_audio_device.h @@ -26,6 +26,9 @@ namespace webrtc { +// This is test API and is in development, so it can be changed/removed without +// notice. + // TestAudioDeviceModule implements an AudioDevice module that can act both as a // capturer and a renderer. It will use 10ms audio frames. class TestAudioDeviceModule : public AudioDeviceModule { @@ -79,7 +82,7 @@ class TestAudioDeviceModule : public AudioDeviceModule { // `renderer` is an object that receives audio data that would have been // played out. Can be nullptr if this device is never used for playing. // Use one of the Create... functions to get these instances. - static rtc::scoped_refptr Create( + static rtc::scoped_refptr Create( TaskQueueFactory* task_queue_factory, std::unique_ptr capturer, std::unique_ptr renderer, diff --git a/third_party/libwebrtc/modules/audio_device/linux/audio_device_alsa_linux.cc b/third_party/libwebrtc/modules/audio_device/linux/audio_device_alsa_linux.cc index 50cf3beb6c972..eab73737c55d0 100644 --- a/third_party/libwebrtc/modules/audio_device/linux/audio_device_alsa_linux.cc +++ b/third_party/libwebrtc/modules/audio_device/linux/audio_device_alsa_linux.cc @@ -10,7 +10,6 @@ #include "modules/audio_device/linux/audio_device_alsa_linux.h" - #include "modules/audio_device/audio_device_config.h" #include "rtc_base/logging.h" #include "rtc_base/system/arch.h" @@ -1053,8 +1052,8 @@ int32_t AudioDeviceLinuxALSA::StartRecording() { } int32_t AudioDeviceLinuxALSA::StopRecording() { - MutexLock lock(&mutex_); - return StopRecordingLocked(); + MutexLock lock(&mutex_); + return StopRecordingLocked(); } int32_t AudioDeviceLinuxALSA::StopRecordingLocked() { @@ -1157,8 +1156,8 @@ int32_t AudioDeviceLinuxALSA::StartPlayout() { } int32_t AudioDeviceLinuxALSA::StopPlayout() { - MutexLock lock(&mutex_); - return StopPlayoutLocked(); + MutexLock lock(&mutex_); + return StopPlayoutLocked(); } int32_t AudioDeviceLinuxALSA::StopPlayoutLocked() { diff --git a/third_party/libwebrtc/modules/audio_device/mac/audio_device_mac.cc b/third_party/libwebrtc/modules/audio_device/mac/audio_device_mac.cc index 527f76a37110f..ed7b0e4669715 100644 --- a/third_party/libwebrtc/modules/audio_device/mac/audio_device_mac.cc +++ b/third_party/libwebrtc/modules/audio_device/mac/audio_device_mac.cc @@ -11,8 +11,8 @@ #include "modules/audio_device/mac/audio_device_mac.h" #include -#include // mach_task_self() -#include // sysctlbyname() +#include // mach_task_self() +#include // sysctlbyname() #include @@ -1355,8 +1355,8 @@ int32_t AudioDeviceMac::StopRecording() { // rendering has ended before stopping itself. if (_recording && captureDeviceIsAlive == 1) { _recording = false; - _doStop = true; // Signal to io proc to stop audio device - mutex_.Unlock(); // Cannot be under lock, risk of deadlock + _doStop = true; // Signal to io proc to stop audio device + mutex_.Unlock(); // Cannot be under lock, risk of deadlock if (!_stopEvent.Wait(TimeDelta::Seconds(2))) { MutexLock lockScoped(&mutex_); RTC_LOG(LS_WARNING) << "Timed out stopping the shared IOProc." @@ -1465,8 +1465,8 @@ int32_t AudioDeviceMac::StopPlayout() { // In the case of a shared device, the IOProc will verify capturing // has ended before stopping itself. _playing = false; - _doStop = true; // Signal to io proc to stop audio device - mutex_.Unlock(); // Cannot be under lock, risk of deadlock + _doStop = true; // Signal to io proc to stop audio device + mutex_.Unlock(); // Cannot be under lock, risk of deadlock if (!_stopEvent.Wait(TimeDelta::Seconds(2))) { MutexLock lockScoped(&mutex_); RTC_LOG(LS_WARNING) << "Timed out stopping the render IOProc." diff --git a/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.cc b/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.cc index 1e3a94edf6b77..aa8b6a9ebebbe 100644 --- a/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.cc +++ b/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.cc @@ -29,12 +29,11 @@ #include "modules/audio_device/win/audio_device_core_win.h" // clang-format on -#include - #include #include #include #include +#include #include #include #include @@ -3256,9 +3255,10 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread() { QueryPerformanceCounter(&t1); // Get the current recording and playout delay. - uint32_t sndCardRecDelay = (uint32_t)( - ((((UINT64)t1.QuadPart * _perfCounterFactor) - recTime) / 10000) + - (10 * syncBufIndex) / _recBlockSize - 10); + uint32_t sndCardRecDelay = + (uint32_t)(((((UINT64)t1.QuadPart * _perfCounterFactor) - recTime) / + 10000) + + (10 * syncBufIndex) / _recBlockSize - 10); uint32_t sndCardPlayDelay = static_cast(_sndCardPlayDelay); while (syncBufIndex >= _recBlockSize) { diff --git a/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.h b/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.h index 7e7ef21157e00..380effb44908a 100644 --- a/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.h +++ b/third_party/libwebrtc/modules/audio_device/win/audio_device_core_win.h @@ -13,12 +13,9 @@ #if (_MSC_VER >= 1400) // only include for VS 2005 and higher -#include "rtc_base/win32.h" - -#include "modules/audio_device/audio_device_generic.h" +#include // CLSID_CWMAudioAEC +//(must be before audioclient.h) -#include // CLSID_CWMAudioAEC - // (must be before audioclient.h) #include // WASAPI #include #include // Avrt @@ -27,8 +24,10 @@ #include // MMDevice #include "api/scoped_refptr.h" +#include "modules/audio_device/audio_device_generic.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/win/scoped_com_initializer.h" +#include "rtc_base/win32.h" // Use Multimedia Class Scheduler Service (MMCSS) to boost the thread priority #pragma comment(lib, "avrt.lib") diff --git a/third_party/libwebrtc/modules/audio_device/win/core_audio_utility_win_unittest.cc b/third_party/libwebrtc/modules/audio_device/win/core_audio_utility_win_unittest.cc index 277f54eb35b6f..fc4a610eef395 100644 --- a/third_party/libwebrtc/modules/audio_device/win/core_audio_utility_win_unittest.cc +++ b/third_party/libwebrtc/modules/audio_device/win/core_audio_utility_win_unittest.cc @@ -9,6 +9,7 @@ */ #include "modules/audio_device/win/core_audio_utility_win.h" + #include "rtc_base/arraysize.h" #include "rtc_base/logging.h" #include "rtc_base/win/scoped_com_initializer.h" diff --git a/third_party/libwebrtc/modules/audio_mixer/BUILD.gn b/third_party/libwebrtc/modules/audio_mixer/BUILD.gn index fe20f3d6c7133..fb038bf677cf2 100644 --- a/third_party/libwebrtc/modules/audio_mixer/BUILD.gn +++ b/third_party/libwebrtc/modules/audio_mixer/BUILD.gn @@ -122,6 +122,7 @@ if (rtc_include_tests) { "../../rtc_base:checks", "../../rtc_base:stringutils", "../../rtc_base:task_queue_for_test", + "../../system_wrappers:metrics", "../../test:test_support", ] } diff --git a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.cc b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.cc index 0c203a1d9f0d3..a1247d7338010 100644 --- a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.cc +++ b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.cc @@ -22,6 +22,7 @@ #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/trace_event.h" +#include "system_wrappers/include/metrics.h" namespace webrtc { @@ -38,62 +39,71 @@ struct AudioMixerImpl::SourceStatus { namespace { -struct SourceFrame { +class SourceFrame { + public: + // Default constructor required by call to `vector::resize()` below. SourceFrame() = default; SourceFrame(AudioMixerImpl::SourceStatus* source_status, AudioFrame* audio_frame, bool muted) - : source_status(source_status), audio_frame(audio_frame), muted(muted) { - RTC_DCHECK(source_status); - RTC_DCHECK(audio_frame); - if (!muted) { - energy = AudioMixerCalculateEnergy(*audio_frame); - } - } + : SourceFrame(source_status, + audio_frame, + muted, + muted ? 0u : AudioMixerCalculateEnergy(*audio_frame)) {} SourceFrame(AudioMixerImpl::SourceStatus* source_status, AudioFrame* audio_frame, bool muted, uint32_t energy) - : source_status(source_status), - audio_frame(audio_frame), - muted(muted), - energy(energy) { + : source_status_(source_status), + audio_frame_(audio_frame), + muted_(muted), + energy_(energy) { RTC_DCHECK(source_status); - RTC_DCHECK(audio_frame); + RTC_DCHECK(audio_frame_); } - AudioMixerImpl::SourceStatus* source_status = nullptr; - AudioFrame* audio_frame = nullptr; - bool muted = true; - uint32_t energy = 0; + AudioMixerImpl::SourceStatus* source_status() { return source_status_; } + const AudioFrame* audio_frame() const { return audio_frame_; } + AudioFrame* mutable_audio_frame() { return audio_frame_; } + bool muted() const { return muted_; } + uint32_t energy() const { return energy_; } + + private: + // The below values are never changed directly, hence only accessors are + // offered. The values can change though via implicit assignment when sorting + // vectors. Pointer values will be nullptr when default constructed as a + // result of calling `vector::resize()`. + AudioMixerImpl::SourceStatus* source_status_ = nullptr; + AudioFrame* audio_frame_ = nullptr; + bool muted_ = true; + uint32_t energy_ = 0u; }; // ShouldMixBefore(a, b) is used to select mixer sources. // Returns true if `a` is preferred over `b` as a source to be mixed. bool ShouldMixBefore(const SourceFrame& a, const SourceFrame& b) { - if (a.muted != b.muted) { - return b.muted; + if (a.muted() != b.muted()) { + return b.muted(); } - const auto a_activity = a.audio_frame->vad_activity_; - const auto b_activity = b.audio_frame->vad_activity_; + const auto a_activity = a.audio_frame()->vad_activity_; + const auto b_activity = b.audio_frame()->vad_activity_; if (a_activity != b_activity) { return a_activity == AudioFrame::kVadActive; } - return a.energy > b.energy; + return a.energy() > b.energy(); } -void RampAndUpdateGain( - rtc::ArrayView mixed_sources_and_frames) { - for (const auto& source_frame : mixed_sources_and_frames) { - float target_gain = source_frame.source_status->is_mixed ? 1.0f : 0.0f; - Ramp(source_frame.source_status->gain, target_gain, - source_frame.audio_frame); - source_frame.source_status->gain = target_gain; +void RampAndUpdateGain(rtc::ArrayView mixed_sources_and_frames) { + for (auto& source_frame : mixed_sources_and_frames) { + float target_gain = source_frame.source_status()->is_mixed ? 1.0f : 0.0f; + Ramp(source_frame.source_status()->gain, target_gain, + source_frame.mutable_audio_frame()); + source_frame.source_status()->gain = target_gain; } } @@ -186,6 +196,7 @@ bool AudioMixerImpl::AddSource(Source* audio_source) { << "Source already added to mixer"; audio_source_list_.emplace_back(new SourceStatus(audio_source, false, 0)); helper_containers_->resize(audio_source_list_.size()); + UpdateSourceCountStats(); return true; } @@ -224,13 +235,13 @@ rtc::ArrayView AudioMixerImpl::GetAudioFromSources( audio_source_mixing_data_view.end(), ShouldMixBefore); int max_audio_frame_counter = max_sources_to_mix_; - int ramp_list_lengh = 0; + int ramp_list_length = 0; int audio_to_mix_count = 0; // Go through list in order and put unmuted frames in result list. - for (const auto& p : audio_source_mixing_data_view) { + for (auto& p : audio_source_mixing_data_view) { // Filter muted. - if (p.muted) { - p.source_status->is_mixed = false; + if (p.muted()) { + p.source_status()->is_mixed = false; continue; } @@ -238,15 +249,16 @@ rtc::ArrayView AudioMixerImpl::GetAudioFromSources( bool is_mixed = false; if (max_audio_frame_counter > 0) { --max_audio_frame_counter; - helper_containers_->audio_to_mix[audio_to_mix_count++] = p.audio_frame; - helper_containers_->ramp_list[ramp_list_lengh++] = - SourceFrame(p.source_status, p.audio_frame, false, -1); + helper_containers_->audio_to_mix[audio_to_mix_count++] = + p.mutable_audio_frame(); + helper_containers_->ramp_list[ramp_list_length++] = + SourceFrame(p.source_status(), p.mutable_audio_frame(), false, -1); is_mixed = true; } - p.source_status->is_mixed = is_mixed; + p.source_status()->is_mixed = is_mixed; } RampAndUpdateGain(rtc::ArrayView( - helper_containers_->ramp_list.data(), ramp_list_lengh)); + helper_containers_->ramp_list.data(), ramp_list_length)); return rtc::ArrayView( helper_containers_->audio_to_mix.data(), audio_to_mix_count); } @@ -263,4 +275,14 @@ bool AudioMixerImpl::GetAudioSourceMixabilityStatusForTest( RTC_LOG(LS_ERROR) << "Audio source unknown"; return false; } + +void AudioMixerImpl::UpdateSourceCountStats() { + size_t current_source_count = audio_source_list_.size(); + // Log to the histogram whenever the maximum number of sources increases. + if (current_source_count > max_source_count_ever_) { + RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.AudioMixer.NewHighestSourceCount", + current_source_count, 1, 20, 20); + max_source_count_ever_ = current_source_count; + } +} } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.h b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.h index 76b1131777dab..e1040defd7937 100644 --- a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.h +++ b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl.h @@ -71,6 +71,8 @@ class AudioMixerImpl : public AudioMixer { private: struct HelperContainers; + void UpdateSourceCountStats() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Compute what audio sources to mix from audio_source_list_. Ramp // in and out. Update mixed status. Mixes up to // kMaximumAmountOfMixedAudioSources audio sources. @@ -94,6 +96,9 @@ class AudioMixerImpl : public AudioMixer { // Component that handles actual adding of audio frames. FrameCombiner frame_combiner_; + + // The highest source count this mixer has ever had. Used for UMA stats. + size_t max_source_count_ever_ = 0; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc index e4b12a7000071..8022332b27800 100644 --- a/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc +++ b/third_party/libwebrtc/modules/audio_mixer/audio_mixer_impl_unittest.cc @@ -28,6 +28,7 @@ #include "rtc_base/checks.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/task_queue_for_test.h" +#include "system_wrappers/include/metrics.h" #include "test/gmock.h" #include "test/gtest.h" @@ -42,6 +43,8 @@ namespace webrtc { namespace { constexpr int kDefaultSampleRateHz = 48000; +const char kSourceCountHistogramName[] = + "WebRTC.Audio.AudioMixer.NewHighestSourceCount"; // Utility function that resets the frame member variables with // sensible defaults. @@ -214,6 +217,41 @@ TEST(AudioMixer, LargestEnergyVadActiveMixed) { } } +TEST(AudioMixer, UpdatesSourceCountHistogram) { + constexpr int kAudioSourcesGroup1 = 5; + constexpr int kAudioSourcesGroup2 = 3; + + const auto mixer = AudioMixerImpl::Create(); + + MockMixerAudioSource participants[kAudioSourcesGroup1 + kAudioSourcesGroup2]; + + // Add the sources in group 1. + for (int i = 0; i < kAudioSourcesGroup1; ++i) { + EXPECT_TRUE(mixer->AddSource(&participants[i])); + EXPECT_EQ(i + 1, metrics::NumSamples(kSourceCountHistogramName)); + EXPECT_EQ(1, metrics::NumEvents(kSourceCountHistogramName, i + 1)); + } + // Remove the sources again. + for (int i = 0; i < kAudioSourcesGroup1; ++i) { + mixer->RemoveSource(&participants[i]); + } + // Add the first group again. This should not add anything new to the + // histogram. + for (int i = 0; i < kAudioSourcesGroup1; ++i) { + EXPECT_TRUE(mixer->AddSource(&participants[i])); + EXPECT_EQ(kAudioSourcesGroup1, + metrics::NumSamples(kSourceCountHistogramName)); + EXPECT_EQ(1, metrics::NumEvents(kSourceCountHistogramName, i + 1)); + } + // Add the second group. This adds to the histogram again. + for (int i = kAudioSourcesGroup1; + i < kAudioSourcesGroup1 + kAudioSourcesGroup2; ++i) { + EXPECT_TRUE(mixer->AddSource(&participants[i])); + EXPECT_EQ(i + 1, metrics::NumSamples(kSourceCountHistogramName)); + EXPECT_EQ(1, metrics::NumEvents(kSourceCountHistogramName, i + 1)); + } +} + TEST(AudioMixer, FrameNotModifiedForSingleParticipant) { const auto mixer = AudioMixerImpl::Create(); diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc b/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc index 44d4514275420..8d6e1cf3d7481 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc +++ b/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc @@ -8,9 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/adaptive_fir_filter.h" - #include "common_audio/intrin.h" + +#include "modules/audio_processing/aec3/adaptive_fir_filter.h" #include "rtc_base/checks.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc b/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc index 5fe7514db1cf1..1e63cf8fe702c 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc +++ b/third_party/libwebrtc/modules/audio_processing/aec3/adaptive_fir_filter_erl_avx2.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h" - #include +#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h" + namespace webrtc { namespace aec3 { diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/echo_path_variability.h b/third_party/libwebrtc/modules/audio_processing/aec3/echo_path_variability.h index 78e4f64b2b7d9..45b33c217cf65 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/echo_path_variability.h +++ b/third_party/libwebrtc/modules/audio_processing/aec3/echo_path_variability.h @@ -14,11 +14,7 @@ namespace webrtc { struct EchoPathVariability { - enum class DelayAdjustment { - kNone, - kBufferFlush, - kNewDetectedDelay - }; + enum class DelayAdjustment { kNone, kBufferFlush, kNewDetectedDelay }; EchoPathVariability(bool gain_change, DelayAdjustment delay_change, diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/fft_data_avx2.cc b/third_party/libwebrtc/modules/audio_processing/aec3/fft_data_avx2.cc index 1fe4bd69c6b05..a4b305607154f 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/fft_data_avx2.cc +++ b/third_party/libwebrtc/modules/audio_processing/aec3/fft_data_avx2.cc @@ -8,11 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/fft_data.h" - #include #include "api/array_view.h" +#include "modules/audio_processing/aec3/fft_data.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/multi_channel_content_detector_unittest.cc b/third_party/libwebrtc/modules/audio_processing/aec3/multi_channel_content_detector_unittest.cc index 8d38dd099175f..3b6e942d88769 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/multi_channel_content_detector_unittest.cc +++ b/third_party/libwebrtc/modules/audio_processing/aec3/multi_channel_content_detector_unittest.cc @@ -453,18 +453,21 @@ TEST(MultiChannelContentDetectorMetrics, ReportsMetrics) { "PersistentMultichannelContentEverDetected")); EXPECT_METRIC_EQ( 1, metrics::NumEvents("WebRTC.Audio.EchoCanceller." - "PersistentMultichannelContentEverDetected", 1)); + "PersistentMultichannelContentEverDetected", + 1)); // Check periodic metric. EXPECT_METRIC_EQ( 2, metrics::NumSamples("WebRTC.Audio.EchoCanceller." "ProcessingPersistentMultichannelContent")); - EXPECT_METRIC_EQ( - 1, metrics::NumEvents("WebRTC.Audio.EchoCanceller." - "ProcessingPersistentMultichannelContent", 0)); - EXPECT_METRIC_EQ( - 1, metrics::NumEvents("WebRTC.Audio.EchoCanceller." - "ProcessingPersistentMultichannelContent", 1)); + EXPECT_METRIC_EQ(1, + metrics::NumEvents("WebRTC.Audio.EchoCanceller." + "ProcessingPersistentMultichannelContent", + 0)); + EXPECT_METRIC_EQ(1, + metrics::NumEvents("WebRTC.Audio.EchoCanceller." + "ProcessingPersistentMultichannelContent", + 1)); } } // namespace webrtc diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/reverb_model.h b/third_party/libwebrtc/modules/audio_processing/aec3/reverb_model.h index 5ba54853daa5f..47ed2f78f3a94 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/reverb_model.h +++ b/third_party/libwebrtc/modules/audio_processing/aec3/reverb_model.h @@ -49,7 +49,6 @@ class ReverbModel { float reverb_decay); private: - std::array reverb_; }; diff --git a/third_party/libwebrtc/modules/audio_processing/aec3/vector_math_avx2.cc b/third_party/libwebrtc/modules/audio_processing/aec3/vector_math_avx2.cc index 0b5f3c142e11a..a9805daf88c3a 100644 --- a/third_party/libwebrtc/modules/audio_processing/aec3/vector_math_avx2.cc +++ b/third_party/libwebrtc/modules/audio_processing/aec3/vector_math_avx2.cc @@ -8,12 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/aec3/vector_math.h" - #include #include #include "api/array_view.h" +#include "modules/audio_processing/aec3/vector_math.h" #include "rtc_base/checks.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core.cc b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core.cc index fbc3239732ae9..b4631460ca9de 100644 --- a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core.cc +++ b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core.cc @@ -123,7 +123,6 @@ const int16_t WebRtcAecm_kSinTable[] = { -2667, -2531, -2395, -2258, -2120, -1981, -1842, -1703, -1563, -1422, -1281, -1140, -998, -856, -713, -571, -428, -285, -142}; - // Moves the pointer to the next entry and inserts `far_spectrum` and // corresponding Q-domain in its buffer. // diff --git a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_c.cc b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_c.cc index d363dd2cfde30..59e0296bbf8cb 100644 --- a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_c.cc +++ b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_c.cc @@ -185,8 +185,9 @@ static void WindowAndFFT(AecmCore* aecm, int16_t scaled_time_signal = time_signal[i] * (1 << time_signal_scaling); fft[i] = (int16_t)((scaled_time_signal * WebRtcAecm_kSqrtHanning[i]) >> 14); scaled_time_signal = time_signal[i + PART_LEN] * (1 << time_signal_scaling); - fft[PART_LEN + i] = (int16_t)( - (scaled_time_signal * WebRtcAecm_kSqrtHanning[PART_LEN - i]) >> 14); + fft[PART_LEN + i] = (int16_t)((scaled_time_signal * + WebRtcAecm_kSqrtHanning[PART_LEN - i]) >> + 14); } // Do forward FFT, then take only the first PART_LEN complex samples, @@ -644,18 +645,18 @@ int RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/8200 } // multiply with Wiener coefficients - efw[i].real = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, hnl[i], 14)); - efw[i].imag = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, hnl[i], 14)); + efw[i].real = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, + hnl[i], 14)); + efw[i].imag = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, + hnl[i], 14)); } } else { // multiply with Wiener coefficients for (i = 0; i < PART_LEN1; i++) { - efw[i].real = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, hnl[i], 14)); - efw[i].imag = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, hnl[i], 14)); + efw[i].real = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, + hnl[i], 14)); + efw[i].imag = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, + hnl[i], 14)); } } diff --git a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_mips.cc b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_mips.cc index 828aa6d2fb3d9..16b03cfe510fa 100644 --- a/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_mips.cc +++ b/third_party/libwebrtc/modules/audio_processing/aecm/aecm_core_mips.cc @@ -569,8 +569,8 @@ static void InverseFFTAndWindow(AecmCore* aecm, [paecm_buf] "+r"(paecm_buf), [i] "=&r"(i), [pp_kSqrtHanning] "+r"(pp_kSqrtHanning), [p_kSqrtHanning] "+r"(p_kSqrtHanning) - : [out_aecm] "r"(out_aecm), - [WebRtcAecm_kSqrtHanning] "r"(WebRtcAecm_kSqrtHanning) + : [out_aecm] "r"(out_aecm), [WebRtcAecm_kSqrtHanning] "r"( + WebRtcAecm_kSqrtHanning) : "hi", "lo", "memory"); // Copy the current block to the old position @@ -1334,10 +1334,10 @@ int WebRtcAecm_ProcessBlock(AecmCore* aecm, } else { // multiply with Wiener coefficients for (i = 0; i < PART_LEN1; i++) { - efw[i].real = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, hnl[i], 14)); - efw[i].imag = (int16_t)( - WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, hnl[i], 14)); + efw[i].real = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].real, + hnl[i], 14)); + efw[i].imag = (int16_t)(WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(dfw[i].imag, + hnl[i], 14)); } } @@ -1424,8 +1424,8 @@ static void ComfortNoise(AecmCore* aecm, "srav %[tmp32], %[tmp32], %[minTrackShift] \n\t" "subu %[tnoise], %[tnoise], %[tmp32] \n\t" : [tmp32] "=&r"(tmp32), [tnoise] "+r"(tnoise) - : - [outLShift32] "r"(outLShift32), [minTrackShift] "r"(minTrackShift)); + : [outLShift32] "r"(outLShift32), [minTrackShift] "r"( + minTrackShift)); } } else { // Reset "too high" counter @@ -1497,8 +1497,8 @@ static void ComfortNoise(AecmCore* aecm, "srav %[tmp32], %[tmp32], %[minTrackShift] \n\t" "subu %[tnoise1], %[tnoise1], %[tmp32] \n\t" : [tmp32] "=&r"(tmp32), [tnoise1] "+r"(tnoise1) - : - [outLShift32] "r"(outLShift32), [minTrackShift] "r"(minTrackShift)); + : [outLShift32] "r"(outLShift32), [minTrackShift] "r"( + minTrackShift)); } } else { // Reset "too high" counter diff --git a/third_party/libwebrtc/modules/audio_processing/agc/legacy/analog_agc.h b/third_party/libwebrtc/modules/audio_processing/agc/legacy/analog_agc.h index 22cd924a938b9..7a231c8a64c9f 100644 --- a/third_party/libwebrtc/modules/audio_processing/agc/legacy/analog_agc.h +++ b/third_party/libwebrtc/modules/audio_processing/agc/legacy/analog_agc.h @@ -11,7 +11,6 @@ #ifndef MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_ #define MODULES_AUDIO_PROCESSING_AGC_LEGACY_ANALOG_AGC_H_ - #include "modules/audio_processing/agc/legacy/digital_agc.h" #include "modules/audio_processing/agc/legacy/gain_control.h" @@ -63,7 +62,7 @@ typedef struct { int32_t upperSecondaryLimit; // = kRxxBufferLen * 2677832; -17 dBfs int32_t lowerSecondaryLimit; // = kRxxBufferLen * 267783; -27 dBfs uint16_t targetIdx; // Table index for corresponding target level - int16_t analogTarget; // Digital reference level in ENV scale + int16_t analogTarget; // Digital reference level in ENV scale // Analog AGC specific variables int32_t filterState[8]; // For downsampling wb to nb @@ -74,8 +73,8 @@ typedef struct { int32_t Rxx160_LPw32; // Low pass filtered frame energies int32_t Rxx16_LPw32Max; // Keeps track of largest energy subframe int32_t Rxx16_vectorw32[kRxxBufferLen]; // Array with subframe energies - int32_t Rxx16w32_array[2][5]; // Energy values of microphone signal - int32_t env[2][10]; // Envelope values of subframes + int32_t Rxx16w32_array[2][5]; // Energy values of microphone signal + int32_t env[2][10]; // Envelope values of subframes int16_t Rxx16pos; // Current position in the Rxx16_vectorw32 int16_t envSum; // Filtered scaled envelope in subframes diff --git a/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/rnn_fc.cc b/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/rnn_fc.cc index 91501fb6e32cb..a13e77461a15a 100644 --- a/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/rnn_fc.cc +++ b/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/rnn_fc.cc @@ -8,10 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include "modules/audio_processing/agc2/rnn_vad/rnn_fc.h" + #include #include -#include "modules/audio_processing/agc2/rnn_vad/rnn_fc.h" #include "rtc_base/checks.h" #include "rtc_base/numerics/safe_conversions.h" #include "third_party/rnnoise/src/rnn_activations.h" diff --git a/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/vector_math_avx2.cc b/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/vector_math_avx2.cc index e4d246d9ab1c2..a875e11daf419 100644 --- a/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/vector_math_avx2.cc +++ b/third_party/libwebrtc/modules/audio_processing/agc2/rnn_vad/vector_math_avx2.cc @@ -8,11 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/audio_processing/agc2/rnn_vad/vector_math.h" - #include #include "api/array_view.h" +#include "modules/audio_processing/agc2/rnn_vad/vector_math.h" #include "rtc_base/checks.h" #include "rtc_base/numerics/safe_conversions.h" diff --git a/third_party/libwebrtc/modules/audio_processing/gain_control_impl.cc b/third_party/libwebrtc/modules/audio_processing/gain_control_impl.cc index edc49d14011e1..5f2b4872b982b 100644 --- a/third_party/libwebrtc/modules/audio_processing/gain_control_impl.cc +++ b/third_party/libwebrtc/modules/audio_processing/gain_control_impl.cc @@ -255,7 +255,6 @@ int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio, return AudioProcessing::kNoError; } - // TODO(ajm): ensure this is called under kAdaptiveAnalog. int GainControlImpl::set_stream_analog_level(int level) { data_dumper_->DumpRaw("gain_control_set_stream_analog_level", 1, &level); @@ -287,7 +286,6 @@ int GainControlImpl::set_mode(Mode mode) { return AudioProcessing::kNoError; } - int GainControlImpl::set_analog_level_limits(int minimum, int maximum) { if (minimum < 0 || maximum > 65535 || maximum < minimum) { return AudioProcessing::kBadParameterError; @@ -302,7 +300,6 @@ int GainControlImpl::set_analog_level_limits(int minimum, int maximum) { return AudioProcessing::kNoError; } - int GainControlImpl::set_target_level_dbfs(int level) { if (level > 31 || level < 0) { return AudioProcessing::kBadParameterError; diff --git a/third_party/libwebrtc/modules/audio_processing/ns/noise_suppressor.cc b/third_party/libwebrtc/modules/audio_processing/ns/noise_suppressor.cc index d66faa6ed400c..7c524dadf3456 100644 --- a/third_party/libwebrtc/modules/audio_processing/ns/noise_suppressor.cc +++ b/third_party/libwebrtc/modules/audio_processing/ns/noise_suppressor.cc @@ -13,6 +13,7 @@ #include #include #include + #include #include "modules/audio_processing/ns/fast_math.h" diff --git a/third_party/libwebrtc/modules/audio_processing/ns/prior_signal_model_estimator.cc b/third_party/libwebrtc/modules/audio_processing/ns/prior_signal_model_estimator.cc index c814658e57a56..f77dcd6daca3d 100644 --- a/third_party/libwebrtc/modules/audio_processing/ns/prior_signal_model_estimator.cc +++ b/third_party/libwebrtc/modules/audio_processing/ns/prior_signal_model_estimator.cc @@ -11,6 +11,7 @@ #include "modules/audio_processing/ns/prior_signal_model_estimator.h" #include + #include #include "modules/audio_processing/ns/fast_math.h" diff --git a/third_party/libwebrtc/modules/audio_processing/ns/quantile_noise_estimator.h b/third_party/libwebrtc/modules/audio_processing/ns/quantile_noise_estimator.h index 67d1512209406..55b0bfa3feed0 100644 --- a/third_party/libwebrtc/modules/audio_processing/ns/quantile_noise_estimator.h +++ b/third_party/libwebrtc/modules/audio_processing/ns/quantile_noise_estimator.h @@ -12,6 +12,7 @@ #define MODULES_AUDIO_PROCESSING_NS_QUANTILE_NOISE_ESTIMATOR_H_ #include + #include #include "api/array_view.h" diff --git a/third_party/libwebrtc/modules/audio_processing/ns/speech_probability_estimator.cc b/third_party/libwebrtc/modules/audio_processing/ns/speech_probability_estimator.cc index fce9bc8e07c5b..65f17f4af217e 100644 --- a/third_party/libwebrtc/modules/audio_processing/ns/speech_probability_estimator.cc +++ b/third_party/libwebrtc/modules/audio_processing/ns/speech_probability_estimator.cc @@ -11,6 +11,7 @@ #include "modules/audio_processing/ns/speech_probability_estimator.h" #include + #include #include "modules/audio_processing/ns/fast_math.h" diff --git a/third_party/libwebrtc/modules/audio_processing/ns/wiener_filter.cc b/third_party/libwebrtc/modules/audio_processing/ns/wiener_filter.cc index e14b7970d9f13..1eb50a7166d2c 100644 --- a/third_party/libwebrtc/modules/audio_processing/ns/wiener_filter.cc +++ b/third_party/libwebrtc/modules/audio_processing/ns/wiener_filter.cc @@ -13,6 +13,7 @@ #include #include #include + #include #include "modules/audio_processing/ns/fast_math.h" diff --git a/third_party/libwebrtc/modules/audio_processing/test/conversational_speech/generator.cc b/third_party/libwebrtc/modules/audio_processing/test/conversational_speech/generator.cc index d0bc2f23190b6..4f776fa216b9f 100644 --- a/third_party/libwebrtc/modules/audio_processing/test/conversational_speech/generator.cc +++ b/third_party/libwebrtc/modules/audio_processing/test/conversational_speech/generator.cc @@ -9,9 +9,8 @@ */ #include -#include - #include +#include #include "absl/flags/flag.h" #include "absl/flags/parse.h" diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/delay_based_bwe.cc index 6984a3c548b5b..f0562bc964580 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/delay_based_bwe.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/delay_based_bwe.cc @@ -78,7 +78,7 @@ DelayBasedBwe::DelayBasedBwe(const FieldTrialsView* key_value_config, active_delay_detector_(video_delay_detector_.get()), last_seen_packet_(Timestamp::MinusInfinity()), uma_recorded_(false), - rate_control_(key_value_config, /*send_side=*/true), + rate_control_(*key_value_config, /*send_side=*/true), prev_bitrate_(DataRate::Zero()), prev_state_(BandwidthUsage::kBwNormal) { RTC_LOG(LS_INFO) @@ -198,7 +198,7 @@ void DelayBasedBwe::IncomingPacketFeedback(const PacketResult& packet_feedback, DataRate DelayBasedBwe::TriggerOveruse(Timestamp at_time, absl::optional link_capacity) { RateControlInput input(BandwidthUsage::kBwOverusing, link_capacity); - return rate_control_.Update(&input, at_time); + return rate_control_.Update(input, at_time); } DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( @@ -263,7 +263,7 @@ bool DelayBasedBwe::UpdateEstimate(Timestamp at_time, absl::optional acked_bitrate, DataRate* target_rate) { const RateControlInput input(active_delay_detector_->State(), acked_bitrate); - *target_rate = rate_control_.Update(&input, at_time); + *target_rate = rate_control_.Update(input, at_time); return rate_control_.ValidEstimate(); } diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc index 18111f52baefe..0483dbf54de04 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc @@ -23,6 +23,7 @@ #include "test/gtest.h" #include "test/scenario/scenario.h" +using ::testing::IsEmpty; using ::testing::NiceMock; namespace webrtc { @@ -359,6 +360,28 @@ TEST(GoogCcNetworkControllerTest, ProbeOnRouteChange) { update = controller->OnProcessInterval({.at_time = current_time}); } +TEST(GoogCcNetworkControllerTest, ProbeAfterRouteChangeWhenTransportWritable) { + NetworkControllerTestFixture fixture; + std::unique_ptr controller = + fixture.CreateController(); + Timestamp current_time = Timestamp::Millis(123); + + NetworkControlUpdate update = controller->OnNetworkAvailability( + {.at_time = current_time, .network_available = false}); + EXPECT_THAT(update.probe_cluster_configs, IsEmpty()); + + update = controller->OnNetworkRouteChange( + CreateRouteChange(current_time, 2 * kInitialBitrate, DataRate::Zero(), + 20 * kInitialBitrate)); + // Transport is not writable. So not point in sending a probe. + EXPECT_THAT(update.probe_cluster_configs, IsEmpty()); + + // Probe is sent when transport becomes writable. + update = controller->OnNetworkAvailability( + {.at_time = current_time, .network_available = true}); + EXPECT_THAT(update.probe_cluster_configs, Not(IsEmpty())); +} + // Bandwidth estimation is updated when feedbacks are received. // Feedbacks which show an increasing delay cause the estimation to be reduced. TEST(GoogCcNetworkControllerTest, UpdatesDelayBasedEstimate) { @@ -945,9 +968,7 @@ TEST(GoogCcScenario, FallbackToLossBasedBweWithoutPacketFeedback) { EXPECT_GE(client->target_rate().kbps(), 500); // Update the network to create high loss ratio - net->UpdateConfig([](NetworkSimulationConfig* c) { - c->loss_rate = 0.15; - }); + net->UpdateConfig([](NetworkSimulationConfig* c) { c->loss_rate = 0.15; }); s.RunFor(TimeDelta::Seconds(20)); // Bandwidth decreases thanks to loss based bwe v0. diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc index d425ccef59f64..8fde515934d3c 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc @@ -157,7 +157,8 @@ ProbeControllerConfig::~ProbeControllerConfig() = default; ProbeController::ProbeController(const FieldTrialsView* key_value_config, RtcEventLog* event_log) - : enable_periodic_alr_probing_(false), + : network_available_(true), + enable_periodic_alr_probing_(false), in_rapid_recovery_experiment_(absl::StartsWith( key_value_config->Lookup(kBweRapidRecoveryExperiment), "Enabled")), @@ -368,7 +369,6 @@ void ProbeController::SetNetworkStateEstimate( } void ProbeController::Reset(Timestamp at_time) { - network_available_ = true; bandwidth_limited_cause_ = BandwidthLimitedCause::kDelayBasedLimited; state_ = State::kInit; min_bitrate_to_probe_further_ = DataRate::PlusInfinity(); diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h index fc6f493009eff..ae00182c68965 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h @@ -136,7 +136,8 @@ class ProbeController { void SetNetworkStateEstimate(webrtc::NetworkStateEstimate estimate); // Resets the ProbeController to a state equivalent to as if it was just - // created EXCEPT for `enable_periodic_alr_probing_`. + // created EXCEPT for `enable_periodic_alr_probing_` and + // `network_available_`. void Reset(Timestamp at_time); ABSL_MUST_USE_RESULT std::vector Process( diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc index ebe3b4a8f73df..99efde80e0209 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc @@ -21,6 +21,7 @@ #include "test/gmock.h" #include "test/gtest.h" +using ::testing::IsEmpty; using ::testing::NiceMock; namespace webrtc { @@ -428,6 +429,34 @@ TEST(ProbeControllerTest, PeriodicProbingAfterReset) { EXPECT_EQ(probes[0].target_data_rate, kStartBitrate * 2); } +TEST(ProbeControllerTest, NoProbesWhenTransportIsNotWritable) { + ProbeControllerFixture fixture; + std::unique_ptr probe_controller = + fixture.CreateController(); + probe_controller->EnablePeriodicAlrProbing(true); + + std::vector probes = + probe_controller->OnNetworkAvailability({.network_available = false}); + EXPECT_THAT(probes, IsEmpty()); + EXPECT_THAT(probe_controller->SetBitrates(kMinBitrate, kStartBitrate, + kMaxBitrate, fixture.CurrentTime()), + IsEmpty()); + fixture.AdvanceTime(TimeDelta::Seconds(10)); + EXPECT_THAT(probe_controller->Process(fixture.CurrentTime()), IsEmpty()); + + // Controller is reset after a network route change. + // But, a probe should not be sent since the transport is not writable. + // Transport is not writable until after DTLS negotiation completes. + // However, the bitrate constraints may change. + probe_controller->Reset(fixture.CurrentTime()); + EXPECT_THAT( + probe_controller->SetBitrates(2 * kMinBitrate, 2 * kStartBitrate, + 2 * kMaxBitrate, fixture.CurrentTime()), + IsEmpty()); + fixture.AdvanceTime(TimeDelta::Seconds(10)); + EXPECT_THAT(probe_controller->Process(fixture.CurrentTime()), IsEmpty()); +} + TEST(ProbeControllerTest, TestExponentialProbingOverflow) { ProbeControllerFixture fixture; std::unique_ptr probe_controller = diff --git a/third_party/libwebrtc/modules/congestion_controller/include/receive_side_congestion_controller.h b/third_party/libwebrtc/modules/congestion_controller/include/receive_side_congestion_controller.h index 8e0f755cd603c..8d81ccbe69982 100644 --- a/third_party/libwebrtc/modules/congestion_controller/include/receive_side_congestion_controller.h +++ b/third_party/libwebrtc/modules/congestion_controller/include/receive_side_congestion_controller.h @@ -44,11 +44,6 @@ class ReceiveSideCongestionController : public CallStatsObserver { void OnReceivedPacket(const RtpPacketReceived& packet, MediaType media_type); - // TODO(perkj, bugs.webrtc.org/14859): Remove all usage. This method is - // currently not used by PeerConnections. - virtual void OnReceivedPacket(int64_t arrival_time_ms, - size_t payload_size, - const RTPHeader& header); // Implements CallStatsObserver. void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override; diff --git a/third_party/libwebrtc/modules/congestion_controller/pcc/bitrate_controller.cc b/third_party/libwebrtc/modules/congestion_controller/pcc/bitrate_controller.cc index 16b8e6966fa1c..1a9cddb5191c3 100644 --- a/third_party/libwebrtc/modules/congestion_controller/pcc/bitrate_controller.cc +++ b/third_party/libwebrtc/modules/congestion_controller/pcc/bitrate_controller.cc @@ -17,7 +17,6 @@ #include #include - namespace webrtc { namespace pcc { diff --git a/third_party/libwebrtc/modules/congestion_controller/receive_side_congestion_controller.cc b/third_party/libwebrtc/modules/congestion_controller/receive_side_congestion_controller.cc index cc314699f77a7..d4c745b5465c8 100644 --- a/third_party/libwebrtc/modules/congestion_controller/receive_side_congestion_controller.cc +++ b/third_party/libwebrtc/modules/congestion_controller/receive_side_congestion_controller.cc @@ -106,19 +106,6 @@ void ReceiveSideCongestionController::OnReceivedPacket( } } -void ReceiveSideCongestionController::OnReceivedPacket( - int64_t arrival_time_ms, - size_t payload_size, - const RTPHeader& header) { - remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size, header); - if (!header.extension.hasTransportSequenceNumber) { - // Receive-side BWE. - MutexLock lock(&mutex_); - PickEstimator(header.extension.hasAbsoluteSendTime); - rbe_->IncomingPacket(arrival_time_ms, payload_size, header); - } -} - void ReceiveSideCongestionController::OnBitrateChanged(int bitrate_bps) { remote_estimator_proxy_.OnBitrateChanged(bitrate_bps); } diff --git a/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_adapter.cc b/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_adapter.cc index e83d09d263c5b..be17e5047252b 100644 --- a/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_adapter.cc +++ b/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_adapter.cc @@ -85,7 +85,6 @@ bool InFlightBytesTracker::NetworkRouteComparator::operator()( TransportFeedbackAdapter::TransportFeedbackAdapter() = default; - void TransportFeedbackAdapter::AddPacket(const RtpPacketSendInfo& packet_info, size_t overhead_bytes, Timestamp creation_time) { @@ -213,51 +212,52 @@ TransportFeedbackAdapter::ProcessTransportFeedbackInner( size_t failed_lookups = 0; size_t ignored = 0; - feedback.ForAllPackets([&](uint16_t sequence_number, - TimeDelta delta_since_base) { - int64_t seq_num = seq_num_unwrapper_.Unwrap(sequence_number); - - if (seq_num > last_ack_seq_num_) { - // Starts at history_.begin() if last_ack_seq_num_ < 0, since any valid - // sequence number is >= 0. - for (auto it = history_.upper_bound(last_ack_seq_num_); - it != history_.upper_bound(seq_num); ++it) { - in_flight_.RemoveInFlightPacketBytes(it->second); - } - last_ack_seq_num_ = seq_num; - } - - auto it = history_.find(seq_num); - if (it == history_.end()) { - ++failed_lookups; - return; - } - - if (it->second.sent.send_time.IsInfinite()) { - // TODO(srte): Fix the tests that makes this happen and make this a - // DCHECK. - RTC_DLOG(LS_ERROR) - << "Received feedback before packet was indicated as sent"; - return; - } - - PacketFeedback packet_feedback = it->second; - if (delta_since_base.IsFinite()) { - packet_feedback.receive_time = - current_offset_ + delta_since_base.RoundDownTo(TimeDelta::Millis(1)); - // Note: Lost packets are not removed from history because they might be - // reported as received by a later feedback. - history_.erase(it); - } - if (packet_feedback.network_route == network_route_) { - PacketResult result; - result.sent_packet = packet_feedback.sent; - result.receive_time = packet_feedback.receive_time; - packet_result_vector.push_back(result); - } else { - ++ignored; - } - }); + feedback.ForAllPackets( + [&](uint16_t sequence_number, TimeDelta delta_since_base) { + int64_t seq_num = seq_num_unwrapper_.Unwrap(sequence_number); + + if (seq_num > last_ack_seq_num_) { + // Starts at history_.begin() if last_ack_seq_num_ < 0, since any + // valid sequence number is >= 0. + for (auto it = history_.upper_bound(last_ack_seq_num_); + it != history_.upper_bound(seq_num); ++it) { + in_flight_.RemoveInFlightPacketBytes(it->second); + } + last_ack_seq_num_ = seq_num; + } + + auto it = history_.find(seq_num); + if (it == history_.end()) { + ++failed_lookups; + return; + } + + if (it->second.sent.send_time.IsInfinite()) { + // TODO(srte): Fix the tests that makes this happen and make this a + // DCHECK. + RTC_DLOG(LS_ERROR) + << "Received feedback before packet was indicated as sent"; + return; + } + + PacketFeedback packet_feedback = it->second; + if (delta_since_base.IsFinite()) { + packet_feedback.receive_time = + current_offset_ + + delta_since_base.RoundDownTo(TimeDelta::Millis(1)); + // Note: Lost packets are not removed from history because they might + // be reported as received by a later feedback. + history_.erase(it); + } + if (packet_feedback.network_route == network_route_) { + PacketResult result; + result.sent_packet = packet_feedback.sent; + result.receive_time = packet_feedback.receive_time; + packet_result_vector.push_back(result); + } else { + ++ignored; + } + }); if (failed_lookups > 0) { RTC_LOG(LS_WARNING) << "Failed to lookup send time for " << failed_lookups diff --git a/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_demuxer.cc b/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_demuxer.cc index 469c21434afeb..5a6a2e1e9bb8e 100644 --- a/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_demuxer.cc +++ b/third_party/libwebrtc/modules/congestion_controller/rtp/transport_feedback_demuxer.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ #include "modules/congestion_controller/rtp/transport_feedback_demuxer.h" + #include "absl/algorithm/container.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc index 988d1740d3edc..7e436382df7e8 100644 --- a/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc @@ -21,6 +21,7 @@ #include "modules/desktop_capture/mouse_cursor.h" #include "modules/desktop_capture/mouse_cursor_monitor.h" #include "rtc_base/checks.h" +#include "rtc_base/logging.h" namespace webrtc { @@ -104,6 +105,11 @@ DesktopFrameWithCursor::DesktopFrameWithCursor( cursor_rect_.IntersectWith(DesktopRect::MakeSize(size())); if (!previous_cursor_rect.equals(cursor_rect_)) { + RTC_LOG(LS_VERBOSE) << "[MOUSE] cursors moved => cursor_rect=(" + << cursor_rect_.top_left().x() << "," + << cursor_rect_.top_left().y() << ") (" + << cursor_rect_.size().width() << "x" + << cursor_rect_.size().height() << ")"; mutable_updated_region()->AddRect(cursor_rect_); // TODO(crbug:1323241) Update this code to properly handle the case where // |previous_cursor_rect| is outside of the boundaries of |frame|. @@ -112,6 +118,11 @@ DesktopFrameWithCursor::DesktopFrameWithCursor( // we're running on. mutable_updated_region()->AddRect(previous_cursor_rect); } else if (cursor_changed) { + RTC_LOG(LS_VERBOSE) << "[MOUSE] cursor changed => cursor_rect=(" + << cursor_rect_.top_left().x() << "," + << cursor_rect_.top_left().y() << ") (" + << cursor_rect_.size().width() << "x" + << cursor_rect_.size().height() << ")"; mutable_updated_region()->AddRect(cursor_rect_); } diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc index 6b741ef4bbd8c..9f20b56c350e5 100644 --- a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc @@ -21,7 +21,7 @@ namespace { enum class SequentialDesktopCapturerId { kUnknown = 0, kWgcCapturerWin = 1, - kScreenCapturerWinMagnifier = 2, + // kScreenCapturerWinMagnifier = 2, kWindowCapturerWinGdi = 3, kScreenCapturerWinGdi = 4, kScreenCapturerWinDirectx = 5, @@ -35,9 +35,6 @@ void RecordCapturerImpl(uint32_t capturer_id) { case DesktopCapturerId::kWgcCapturerWin: sequential_id = SequentialDesktopCapturerId::kWgcCapturerWin; break; - case DesktopCapturerId::kScreenCapturerWinMagnifier: - sequential_id = SequentialDesktopCapturerId::kScreenCapturerWinMagnifier; - break; case DesktopCapturerId::kWindowCapturerWinGdi: sequential_id = SequentialDesktopCapturerId::kWindowCapturerWinGdi; break; diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h index 88990cd0a9ec8..775531081ba55 100644 --- a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h @@ -135,12 +135,6 @@ class RTC_EXPORT DesktopCaptureOptions { enumerate_current_process_windows_ = enumerate_current_process_windows; } - bool allow_use_magnification_api() const { - return allow_use_magnification_api_; - } - void set_allow_use_magnification_api(bool allow) { - allow_use_magnification_api_ = allow; - } // Allowing directx based capturer or not, this capturer works on windows 7 // with platform update / windows 8 or upper. bool allow_directx_capturer() const { return allow_directx_capturer_; } @@ -238,7 +232,6 @@ class RTC_EXPORT DesktopCaptureOptions { #if defined(WEBRTC_WIN) bool enumerate_current_process_windows_ = true; - bool allow_use_magnification_api_ = false; bool allow_directx_capturer_ = false; bool allow_cropping_window_capturer_ = false; #if defined(RTC_ENABLE_WIN_WGC) diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_frame.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_frame.cc index 030bd8f0607be..be61196c7d711 100644 --- a/third_party/libwebrtc/modules/desktop_capture/desktop_frame.cc +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_frame.cc @@ -133,6 +133,7 @@ void DesktopFrame::CopyFrameInfoFrom(const DesktopFrame& other) { *mutable_updated_region() = other.updated_region(); set_top_left(other.top_left()); set_icc_profile(other.icc_profile()); + set_may_contain_cursor(other.may_contain_cursor()); } void DesktopFrame::MoveFrameInfoFrom(DesktopFrame* other) { @@ -142,6 +143,7 @@ void DesktopFrame::MoveFrameInfoFrom(DesktopFrame* other) { mutable_updated_region()->Swap(other->mutable_updated_region()); set_top_left(other->top_left()); set_icc_profile(other->icc_profile()); + set_may_contain_cursor(other->may_contain_cursor()); } bool DesktopFrame::FrameDataIsBlack() const { diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_frame_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_frame_unittest.cc index 22df1a7f53d5b..e690e6ae5b95f 100644 --- a/third_party/libwebrtc/modules/desktop_capture/desktop_frame_unittest.cc +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_frame_unittest.cc @@ -44,8 +44,8 @@ void RunTest(const TestData& test) { auto dest_frame = CreateTestFrame(test.dest_frame_rect, 0); auto src_frame = CreateTestFrame(test.src_frame_rect, 0xff); - dest_frame->CopyIntersectingPixelsFrom( - *src_frame, test.horizontal_scale, test.vertical_scale); + dest_frame->CopyIntersectingPixelsFrom(*src_frame, test.horizontal_scale, + test.vertical_scale); // Translate the expected overlap rect to be relative to the dest frame/rect. DesktopVector dest_frame_origin = test.dest_frame_rect.top_left(); @@ -105,6 +105,7 @@ TEST(DesktopFrameTest, FrameDataSwitchesBetweenNonBlackAndBlack) { } TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRects) { + // clang-format off const TestData tests[] = { {"0 origin", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -118,6 +119,7 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRects) { 1.0, 1.0, DesktopRect::MakeXYWH(-1, -1, 2, 2)} }; + // clang-format on RunTests(tests, arraysize(tests)); } @@ -125,6 +127,7 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRects) { TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRectsScaled) { // The scale factors shouldn't affect matching rects (they're only applied // to any difference between the origins) + // clang-format off const TestData tests[] = { {"0 origin 2x", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -150,11 +153,13 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsMatchingRectsScaled) { 0.5, 0.5, DesktopRect::MakeXYWH(-1, -1, 2, 2)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRects) { + // clang-format off const TestData tests[] = { {"0 origin top left", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -174,11 +179,13 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRects) { 1.0, 1.0, DesktopRect::MakeXYWH(-1, 0, 1, 1)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRectsScaled) { + // clang-format off const TestData tests[] = { {"0 origin top left 2x", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -222,12 +229,14 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsFullyContainedRectsScaled) { 0.5, 0.5, DesktopRect::MakeXYWH(-1, -1, 1, 1)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRects) { + // clang-format off const TestData tests[] = { {"Top left", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -253,11 +262,13 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRects) { 1.0, 1.0, DesktopRect::MakeXYWH(0, 1, 1, 1)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRectsScaled) { + // clang-format off const TestData tests[] = { {"Top left 2x", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -283,12 +294,14 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsPartiallyContainedRectsScaled) { 0.5, 0.5, DesktopRect::MakeXYWH(0, 1, 1, 1)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRects) { + // clang-format off const TestData tests[] = { {"Left", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -315,11 +328,13 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRects) { 1.0, 1.0, DesktopRect::MakeXYWH(0, 0, 0, 0)} }; + // clang-format on RunTests(tests, arraysize(tests)); } TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRectsScaled) { + // clang-format off const TestData tests[] = { {"Left 2x", DesktopRect::MakeXYWH(0, 0, 2, 2), @@ -346,6 +361,7 @@ TEST(DesktopFrameTest, CopyIntersectingPixelsUncontainedRectsScaled) { 0.5, 0.5, DesktopRect::MakeXYWH(0, 0, 0, 0)} }; + // clang-format on RunTests(tests, arraysize(tests)); } diff --git a/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc b/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc index e0975570ba0c2..68ee8321b470d 100644 --- a/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc +++ b/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc @@ -9,6 +9,7 @@ */ #include "modules/desktop_capture/full_screen_application_handler.h" + #include "rtc_base/logging.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc b/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc index d0bc9c7ca682b..956a0b4663d52 100644 --- a/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc +++ b/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc @@ -9,6 +9,7 @@ */ #include "modules/desktop_capture/full_screen_window_detector.h" + #include "modules/desktop_capture/full_screen_application_handler.h" #include "rtc_base/time_utils.h" diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc index 8d9e956779e0d..ebe6779e31be9 100644 --- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc +++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc @@ -24,12 +24,12 @@ namespace { using xdg_portal::kScreenCastInterfaceName; using xdg_portal::PrepareSignalHandle; using xdg_portal::RequestResponse; +using xdg_portal::RequestResponseFromPortalResponse; using xdg_portal::RequestSessionProxy; using xdg_portal::SetupRequestResponseSignal; using xdg_portal::SetupSessionRequestHandlers; using xdg_portal::StartSessionRequest; using xdg_portal::TearDownSession; -using xdg_portal::RequestResponseFromPortalResponse; } // namespace diff --git a/third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.h b/third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.h index f795a22030d2f..060cdb5a615da 100644 --- a/third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.h +++ b/third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.h @@ -12,6 +12,7 @@ #define MODULES_DESKTOP_CAPTURE_MAC_FULL_SCREEN_MAC_APPLICATION_HANDLER_H_ #include + #include "modules/desktop_capture/full_screen_application_handler.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.h b/third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.h index 7be05cc63981f..e4a2cc2fc9aa5 100644 --- a/third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.h +++ b/third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.h @@ -36,10 +36,9 @@ class DisplayStreamManager; // A class to perform video frame capturing for mac. class ScreenCapturerMac final : public DesktopCapturer { public: - ScreenCapturerMac( - rtc::scoped_refptr desktop_config_monitor, - bool detect_updated_region, - bool allow_iosurface); + ScreenCapturerMac(rtc::scoped_refptr desktop_config_monitor, + bool detect_updated_region, + bool allow_iosurface); ~ScreenCapturerMac() override; ScreenCapturerMac(const ScreenCapturerMac&) = delete; diff --git a/third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.h b/third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.h index a9b1e7007cb54..34d1313234dce 100644 --- a/third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.h +++ b/third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.h @@ -14,6 +14,7 @@ #include #include + #include "api/function_view.h" #include "modules/desktop_capture/desktop_capture_types.h" #include "modules/desktop_capture/desktop_capturer.h" diff --git a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc index f8261a90b0da2..04e72b3e9f85c 100644 --- a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc +++ b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc @@ -10,7 +10,6 @@ #include "modules/desktop_capture/screen_capturer_helper.h" - namespace webrtc { void ScreenCapturerHelper::ClearInvalidRegion() { diff --git a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_integration_test.cc b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_integration_test.cc index b33427ad42a0b..13170bc2888c2 100644 --- a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_integration_test.cc +++ b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_integration_test.cc @@ -171,12 +171,6 @@ class ScreenCapturerIntegrationTest : public ::testing::Test { MaybeCreateDirectxCapturer(); return true; } - - void CreateMagnifierCapturer() { - DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); - options.set_allow_use_magnification_api(true); - capturer_ = DesktopCapturer::CreateScreenCapturer(options); - } #endif // defined(WEBRTC_WIN) std::unique_ptr capturer_; @@ -330,35 +324,6 @@ TEST_F(ScreenCapturerIntegrationTest, DISABLED_TwoDirectxCapturers) { TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); } -TEST_F(ScreenCapturerIntegrationTest, - DISABLED_CaptureUpdatedRegionWithMagnifierCapturer) { - // On Windows 8 or later, magnifier APIs return a frame with a border on test - // environment, so disable these tests. - // Bug https://bugs.chromium.org/p/webrtc/issues/detail?id=6844 - // TODO(zijiehe): Find the root cause of the border and failure, which cannot - // reproduce on my dev machine. - if (rtc::rtc_win::GetVersion() >= rtc::rtc_win::Version::VERSION_WIN8) { - return; - } - CreateMagnifierCapturer(); - TestCaptureUpdatedRegion(); -} - -TEST_F(ScreenCapturerIntegrationTest, DISABLED_TwoMagnifierCapturers) { - // On Windows 8 or later, magnifier APIs return a frame with a border on test - // environment, so disable these tests. - // Bug https://bugs.chromium.org/p/webrtc/issues/detail?id=6844 - // TODO(zijiehe): Find the root cause of the border and failure, which cannot - // reproduce on my dev machine. - if (rtc::rtc_win::GetVersion() >= rtc::rtc_win::Version::VERSION_WIN8) { - return; - } - CreateMagnifierCapturer(); - std::unique_ptr capturer2 = std::move(capturer_); - CreateMagnifierCapturer(); - TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); -} - TEST_F(ScreenCapturerIntegrationTest, DISABLED_MaybeCaptureUpdatedRegionWithDirectxCapturer) { if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN8) { diff --git a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_unittest.cc index 8f5fe631f10bc..4654000a82aa7 100644 --- a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_unittest.cc +++ b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_unittest.cc @@ -40,7 +40,7 @@ class ScreenCapturerTest : public ::testing::Test { protected: #if defined(WEBRTC_WIN) // Enable allow_directx_capturer in DesktopCaptureOptions, but let - // DesktopCapturer::CreateScreenCapturer to decide whether a DirectX capturer + // DesktopCapturer::CreateScreenCapturer decide whether a DirectX capturer // should be used. void MaybeCreateDirectxCapturer() { DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); @@ -57,12 +57,6 @@ class ScreenCapturerTest : public ::testing::Test { MaybeCreateDirectxCapturer(); return true; } - - void CreateMagnifierCapturer() { - DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); - options.set_allow_use_magnification_api(true); - capturer_ = DesktopCapturer::CreateScreenCapturer(options); - } #endif // defined(WEBRTC_WIN) std::unique_ptr capturer_; @@ -173,8 +167,7 @@ TEST_F(ScreenCapturerTest, UseSharedBuffers) { EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); } -TEST_F(ScreenCapturerTest, UseMagnifier) { - CreateMagnifierCapturer(); +TEST_F(ScreenCapturerTest, GdiIsDefault) { std::unique_ptr frame; EXPECT_CALL(callback_, OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) @@ -183,6 +176,7 @@ TEST_F(ScreenCapturerTest, UseMagnifier) { capturer_->Start(&callback_); capturer_->CaptureFrame(); ASSERT_TRUE(frame); + EXPECT_EQ(frame->capturer_id(), DesktopCapturerId::kScreenCapturerWinGdi); } TEST_F(ScreenCapturerTest, UseDirectxCapturer) { @@ -198,6 +192,7 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturer) { capturer_->Start(&callback_); capturer_->CaptureFrame(); ASSERT_TRUE(frame); + EXPECT_EQ(frame->capturer_id(), DesktopCapturerId::kScreenCapturerWinDirectx); } TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { @@ -217,6 +212,7 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { ASSERT_TRUE(frame); ASSERT_TRUE(frame->shared_memory()); EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); + EXPECT_EQ(frame->capturer_id(), DesktopCapturerId::kScreenCapturerWinDirectx); } #endif // defined(WEBRTC_WIN) diff --git a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc index b5935dc3162a2..e91764360f494 100644 --- a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc +++ b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc @@ -18,14 +18,15 @@ #include "modules/desktop_capture/rgba_color.h" #include "modules/desktop_capture/win/screen_capturer_win_directx.h" #include "modules/desktop_capture/win/screen_capturer_win_gdi.h" -#include "modules/desktop_capture/win/screen_capturer_win_magnifier.h" namespace webrtc { namespace { -std::unique_ptr CreateScreenCapturerWinDirectx() { - std::unique_ptr capturer(new ScreenCapturerWinDirectx()); +std::unique_ptr CreateScreenCapturerWinDirectx( + const DesktopCaptureOptions& options) { + std::unique_ptr capturer( + new ScreenCapturerWinDirectx(options)); capturer.reset(new BlankDetectorDesktopCapturerWrapper( std::move(capturer), RgbaColor(0, 0, 0, 0))); return capturer; @@ -36,26 +37,22 @@ std::unique_ptr CreateScreenCapturerWinDirectx() { // static std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( const DesktopCaptureOptions& options) { + // Default capturer if no options are enabled is GDI. std::unique_ptr capturer(new ScreenCapturerWinGdi(options)); + + // If DirectX is enabled use it as main capturer with GDI as fallback. if (options.allow_directx_capturer()) { // `dxgi_duplicator_controller` should be alive in this scope to ensure it // won't unload DxgiDuplicatorController. auto dxgi_duplicator_controller = DxgiDuplicatorController::Instance(); if (ScreenCapturerWinDirectx::IsSupported()) { capturer.reset(new FallbackDesktopCapturerWrapper( - CreateScreenCapturerWinDirectx(), std::move(capturer))); + CreateScreenCapturerWinDirectx(options), std::move(capturer))); + return capturer; } } - if (options.allow_use_magnification_api()) { - // ScreenCapturerWinMagnifier cannot work on Windows XP or earlier, as well - // as 64-bit only Windows, and it may randomly crash on multi-screen - // systems. So we may need to fallback to use original capturer. - capturer.reset(new FallbackDesktopCapturerWrapper( - std::unique_ptr(new ScreenCapturerWinMagnifier()), - std::move(capturer))); - } - + // Use GDI as default capturer without any fallback solution. return capturer; } diff --git a/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc b/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc index 599cdacd5b3e3..9c64125b4ed19 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc +++ b/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc @@ -147,12 +147,18 @@ bool DxgiOutputDuplicator::ReleaseFrame() { return true; } -void DxgiOutputDuplicator::LogMouseCursor( +bool DxgiOutputDuplicator::ContainsMouseCursor( const DXGI_OUTDUPL_FRAME_INFO& frame_info) { + // The DXGI_OUTDUPL_POINTER_POSITION structure that describes the most recent + // mouse position is only valid if the LastMouseUpdateTime member is a non- + // zero value. + if (frame_info.LastMouseUpdateTime.QuadPart == 0) + return false; + // Ignore cases when the mouse shape has changed and not the position. const bool new_pointer_shape = (frame_info.PointerShapeBufferSize != 0); if (new_pointer_shape) - return; + return false; // The mouse cursor has moved and we can now query if the mouse pointer is // drawn onto the desktop image or not to decide if we must draw the mouse @@ -163,12 +169,10 @@ void DxgiOutputDuplicator::LogMouseCursor( // desktop image, the pointer position data that is reported by // AcquireNextFrame indicates that a separate pointer isn’t visible, hence // `frame_info.PointerPosition.Visible` is false. - // TODO(http://crbug.com/1421656): evaluate this UMA and possibly call - // set_may_contain_cursor(cursor_embedded_in_frame) on the captured frame to - // avoid rendering the cursor twice. const bool cursor_embedded_in_frame = !frame_info.PointerPosition.Visible; RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.Win.DirectXCursorEmbedded", cursor_embedded_in_frame); + return cursor_embedded_in_frame; } bool DxgiOutputDuplicator::Duplicate(Context* context, @@ -194,12 +198,7 @@ bool DxgiOutputDuplicator::Duplicate(Context* context, return false; } - // The DXGI_OUTDUPL_POINTER_POSITION structure that describes the most recent - // mouse position is only valid if the LastMouseUpdateTime member is a non- - // zero value. - if (frame_info.LastMouseUpdateTime.QuadPart != 0) { - LogMouseCursor(frame_info); - } + const bool cursor_embedded_in_frame = ContainsMouseCursor(frame_info); // We need to merge updated region with the one from context, but only spread // updated region from current frame. So keeps a copy of updated region from @@ -239,6 +238,7 @@ bool DxgiOutputDuplicator::Duplicate(Context* context, last_frame_offset_ = offset; updated_region.Translate(offset.x(), offset.y()); target->mutable_updated_region()->AddRegion(updated_region); + target->set_may_contain_cursor(cursor_embedded_in_frame); num_frames_captured_++; return texture_->Release() && ReleaseFrame(); } @@ -258,6 +258,7 @@ bool DxgiOutputDuplicator::Duplicate(Context* context, } updated_region.Translate(offset.x(), offset.y()); target->mutable_updated_region()->AddRegion(updated_region); + target->set_may_contain_cursor(cursor_embedded_in_frame); } else { // If we were at the very first frame, and capturing failed, the // context->updated_region should be kept unchanged for next attempt. diff --git a/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.h b/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.h index c44c9f29827cb..a4ce035d8b853 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.h +++ b/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.h @@ -97,10 +97,10 @@ class DxgiOutputDuplicator { bool DoDetectUpdatedRegion(const DXGI_OUTDUPL_FRAME_INFO& frame_info, DesktopRegion* updated_region); - // Adds boolean WebRTC.DesktopCapture.Win.DirectXCursorEmbedded UMA stat which - // contains true if the mouse cursor is embedded in the captured frame and - // false if not. - void LogMouseCursor(const DXGI_OUTDUPL_FRAME_INFO& frame_info); + // Returns true if the mouse cursor is embedded in the captured frame and + // false if not. Also logs the same boolean as + // WebRTC.DesktopCapture.Win.DirectXCursorEmbedded UMA. + bool ContainsMouseCursor(const DXGI_OUTDUPL_FRAME_INFO& frame_info); bool ReleaseFrame(); diff --git a/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h b/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h index c97cbe252b5c8..286e8e5cb942d 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h +++ b/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h @@ -12,6 +12,7 @@ #define MODULES_DESKTOP_CAPTURE_WIN_FULL_SCREEN_WIN_APPLICATION_HANDLER_H_ #include + #include "modules/desktop_capture/full_screen_application_handler.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.h b/third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.h index 9aa838ab8d304..71c79b9ab3d29 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.h +++ b/third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.h @@ -15,8 +15,8 @@ // Forward declare HMONITOR in a windows.h compatible way so that we can avoid // including windows.h. #define WEBRTC_DECLARE_HANDLE(name) \ -struct name##__; \ -typedef struct name##__* name + struct name##__; \ + typedef struct name##__* name WEBRTC_DECLARE_HANDLE(HMONITOR); #undef WEBRTC_DECLARE_HANDLE #endif diff --git a/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc b/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc index 3aaac03057036..0ed2e12423fcc 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc +++ b/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc @@ -104,6 +104,12 @@ int ScreenCapturerWinDirectx::GetIndexFromScreenId( ScreenCapturerWinDirectx::ScreenCapturerWinDirectx() : controller_(DxgiDuplicatorController::Instance()) {} +ScreenCapturerWinDirectx::ScreenCapturerWinDirectx( + const DesktopCaptureOptions& options) + : ScreenCapturerWinDirectx() { + options_ = options; +} + ScreenCapturerWinDirectx::~ScreenCapturerWinDirectx() = default; void ScreenCapturerWinDirectx::Start(Callback* callback) { @@ -191,6 +197,12 @@ void ScreenCapturerWinDirectx::CaptureFrame() { capture_time_ms); frame->set_capture_time_ms(capture_time_ms); frame->set_capturer_id(DesktopCapturerId::kScreenCapturerWinDirectx); + // The DXGI Output Duplicator supports embedding the cursor but it is + // only supported on very few display adapters. This switch allows us + // to exclude an integrated cursor for all captured frames. + if (!options_.prefer_cursor_embedded()) { + frame->set_may_contain_cursor(false); + } // TODO(julien.isorce): http://crbug.com/945468. Set the icc profile on // the frame, see WindowCapturerMac::CaptureFrame. diff --git a/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.h b/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.h index 801a0632fce9f..a231643c335d0 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.h +++ b/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.h @@ -70,7 +70,9 @@ class RTC_EXPORT ScreenCapturerWinDirectx : public DesktopCapturer { static int GetIndexFromScreenId(ScreenId id, const std::vector& device_names); - explicit ScreenCapturerWinDirectx(); + // This constructor is deprecated. Please don't use it in new implementations. + ScreenCapturerWinDirectx(); + explicit ScreenCapturerWinDirectx(const DesktopCaptureOptions& options); ~ScreenCapturerWinDirectx() override; @@ -87,6 +89,7 @@ class RTC_EXPORT ScreenCapturerWinDirectx : public DesktopCapturer { private: const rtc::scoped_refptr controller_; + DesktopCaptureOptions options_; // The underlying DxgiDuplicators may retain a reference to the frames that // we ask them to duplicate so that they can continue returning valid frames diff --git a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc index 580c41adf1cce..64247d273927c 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc +++ b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc @@ -100,7 +100,7 @@ WgcCaptureSession::WgcCaptureSession(ComPtr d3d11_device, size_(size) {} WgcCaptureSession::~WgcCaptureSession() { - RemoveEventHandlers(); + RemoveEventHandler(); } HRESULT WgcCaptureSession::StartCapture(const DesktopCaptureOptions& options) { @@ -166,17 +166,6 @@ HRESULT WgcCaptureSession::StartCapture(const DesktopCaptureOptions& options) { return hr; } - // Because `WgcCapturerWin` created a `DispatcherQueue`, and we created - // `frame_pool_` via `Create`, the `FrameArrived` event will be delivered on - // the current thread. - frame_arrived_token_ = std::make_unique(); - auto frame_arrived_handler = - Microsoft::WRL::Callback>( - this, &WgcCaptureSession::OnFrameArrived); - hr = frame_pool_->add_FrameArrived(frame_arrived_handler.Get(), - frame_arrived_token_.get()); - hr = frame_pool_->CreateCaptureSession(item_.Get(), &session_); if (FAILED(hr)) { RecordStartCaptureResult(StartCaptureResult::kCreateCaptureSessionFailed); @@ -207,34 +196,52 @@ HRESULT WgcCaptureSession::StartCapture(const DesktopCaptureOptions& options) { return hr; } -bool WgcCaptureSession::GetFrame(std::unique_ptr* output_frame) { - RTC_DCHECK_RUN_ON(&sequence_checker_); +void WgcCaptureSession::EnsureFrame() { + // Try to process the captured frame and copy it to the `queue_`. + HRESULT hr = ProcessFrame(); + if (SUCCEEDED(hr)) { + RTC_CHECK(queue_.current_frame()); + return; + } + + // We failed to process the frame, but we do have a frame so just return that. + if (queue_.current_frame()) { + RTC_LOG(LS_ERROR) << "ProcessFrame failed, using existing frame: " << hr; + return; + } - // When GetFrame() asks for the first frame it can happen that no frame has - // arrived yet. We therefore try to get a new frame from the frame pool for a - // maximum of 10 times after sleeping for 20ms. We choose 20ms as it's just a - // bit longer than 17ms (for 60fps*) and hopefully avoids unlucky timing - // causing us to wait two frames when we mostly seem to only need to wait for - // one. This approach should ensure that GetFrame() always delivers a valid - // frame with a max latency of 200ms and often after sleeping only once. - // We also build up an `empty_frame_credit_count_` for each sleep call. As - // long as this credit is above zero, error logs for "empty frame" are - // avoided. The counter is reduced by one for each successful call to - // ProcessFrame() until the number of credits is zero. This counter is only - // expected to be above zero during a short startup phase. The scheme is - // heuristic and based on manual testing. + // ProcessFrame failed and we don't have a current frame. This could indicate + // a startup path where we may need to try/wait a few times to ensure that we + // have a frame. We try to get a new frame from the frame pool for a maximum + // of 10 times after sleeping for 20ms. We choose 20ms as it's just a bit + // longer than 17ms (for 60fps*) and hopefully avoids unlucky timing causing + // us to wait two frames when we mostly seem to only need to wait for one. + // This approach should ensure that GetFrame() always delivers a valid frame + // with a max latency of 200ms and often after sleeping only once. + // The scheme is heuristic and based on manual testing. // (*) On a modern system, the FPS / monitor refresh rate is usually larger // than or equal to 60. + const int max_sleep_count = 10; const int sleep_time_ms = 20; int sleep_count = 0; while (!queue_.current_frame() && sleep_count < max_sleep_count) { sleep_count++; - empty_frame_credit_count_ = sleep_count + 1; webrtc::SleepMs(sleep_time_ms); - ProcessFrame(); + hr = ProcessFrame(); + if (FAILED(hr)) { + RTC_DLOG(LS_WARNING) << "ProcessFrame failed during startup: " << hr; + } } + RTC_LOG_IF(LS_ERROR, !queue_.current_frame()) + << "Unable to process a valid frame even after trying 10 times."; +} + +bool WgcCaptureSession::GetFrame(std::unique_ptr* output_frame) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + + EnsureFrame(); // Return a NULL frame and false as `result` if we still don't have a valid // frame. This will lead to a DesktopCapturer::Result::ERROR_PERMANENT being @@ -281,17 +288,6 @@ HRESULT WgcCaptureSession::CreateMappedTexture( return d3d11_device_->CreateTexture2D(&map_desc, nullptr, &mapped_texture_); } -HRESULT WgcCaptureSession::OnFrameArrived( - WGC::IDirect3D11CaptureFramePool* sender, - IInspectable* event_args) { - RTC_DCHECK_RUN_ON(&sequence_checker_); - HRESULT hr = ProcessFrame(); - if (FAILED(hr)) { - RTC_DLOG(LS_WARNING) << "ProcessFrame failed: " << hr; - } - return hr; -} - HRESULT WgcCaptureSession::ProcessFrame() { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -303,11 +299,6 @@ HRESULT WgcCaptureSession::ProcessFrame() { RTC_DCHECK(is_capture_started_); - queue_.MoveToNextFrame(); - if (queue_.current_frame() && queue_.current_frame()->IsShared()) { - RTC_DLOG(LS_VERBOSE) << "Overwriting frame that is still shared."; - } - ComPtr capture_frame; HRESULT hr = frame_pool_->TryGetNextFrame(&capture_frame); if (FAILED(hr)) { @@ -317,15 +308,19 @@ HRESULT WgcCaptureSession::ProcessFrame() { } if (!capture_frame) { - // Avoid logging errors while we still have credits (or allowance) to - // consider this condition as expected and not as an error. - if (empty_frame_credit_count_ == 0) { + // Avoid logging errors until at least one valid frame has been captured. + if (queue_.current_frame()) { RTC_DLOG(LS_WARNING) << "Frame pool was empty => kFrameDropped."; RecordGetFrameResult(GetFrameResult::kFrameDropped); } return E_FAIL; } + queue_.MoveToNextFrame(); + if (queue_.current_frame() && queue_.current_frame()->IsShared()) { + RTC_DLOG(LS_VERBOSE) << "Overwriting frame that is still shared."; + } + // We need to get `capture_frame` as an `ID3D11Texture2D` so that we can get // the raw image data in the format required by the `DesktopFrame` interface. ComPtr @@ -435,12 +430,8 @@ HRESULT WgcCaptureSession::ProcessFrame() { // Make a copy of the data pointed to by `map_info.pData` to the preallocated // `current_frame` so we are free to unmap our texture. uint8_t* src_data = static_cast(map_info.pData); - uint8_t* dst_data = current_frame->data(); - for (int i = 0; i < image_height; i++) { - memcpy(dst_data, src_data, current_frame->stride()); - dst_data += current_frame->stride(); - src_data += map_info.RowPitch; - } + current_frame->CopyPixelsFrom(src_data, current_frame->stride(), + DesktopRect::MakeSize(current_frame->size())); d3d_context->Unmap(mapped_texture_.Get(), 0); @@ -470,8 +461,6 @@ HRESULT WgcCaptureSession::ProcessFrame() { } } - if (empty_frame_credit_count_ > 0) - --empty_frame_credit_count_; size_ = new_size; RecordGetFrameResult(GetFrameResult::kSuccess); return hr; @@ -484,7 +473,7 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender, RTC_LOG(LS_INFO) << "Capture target has been closed."; item_closed_ = true; - RemoveEventHandlers(); + RemoveEventHandler(); // Do not attempt to free resources in the OnItemClosed handler, as this // causes a race where we try to delete the item that is calling us. Removing @@ -494,16 +483,8 @@ HRESULT WgcCaptureSession::OnItemClosed(WGC::IGraphicsCaptureItem* sender, return S_OK; } -void WgcCaptureSession::RemoveEventHandlers() { +void WgcCaptureSession::RemoveEventHandler() { HRESULT hr; - if (frame_pool_ && frame_arrived_token_) { - hr = frame_pool_->remove_FrameArrived(*frame_arrived_token_); - frame_arrived_token_.reset(); - if (FAILED(hr)) { - RTC_LOG(LS_WARNING) << "Failed to remove FrameArrived event handler: " - << hr; - } - } if (item_ && item_closed_token_) { hr = item_->remove_Closed(*item_closed_token_); item_closed_token_.reset(); diff --git a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.h b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.h index a2d7a87cf19dc..ee15096eab8cb 100644 --- a/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.h +++ b/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.h @@ -72,19 +72,17 @@ class WgcCaptureSession final { ABI::Windows::Graphics::Capture::IGraphicsCaptureItem* sender, IInspectable* event_args); - // Event handler for `frame_pool_`'s FrameArrived event. - HRESULT OnFrameArrived( - ABI::Windows::Graphics::Capture::IDirect3D11CaptureFramePool* sender, - IInspectable* event_args); + // Wraps calls to ProcessFrame and deals with the uniqe start-up phase + // ensuring that we always have one captured frame available. + void EnsureFrame(); // Process the captured frame and copy it to the `queue_`. HRESULT ProcessFrame(); - void RemoveEventHandlers(); + void RemoveEventHandler(); bool allow_zero_hertz() const { return allow_zero_hertz_; } - std::unique_ptr frame_arrived_token_; std::unique_ptr item_closed_token_; // A Direct3D11 Device provided by the caller. We use this to create an @@ -132,16 +130,6 @@ class WgcCaptureSession final { bool item_closed_ = false; bool is_capture_started_ = false; - // Counts number of "empty frame credits" which have built up in GetFrame() - // when a sequence of calls to ProcessFrame() was called with 20ms sleep calls - // between each. The counter is reduced by one (to a minimum of zero) when - // ProcessFrame() succeeds. As long as the counter is larger than zero, calls - // to RecordGetFrameResult(kTryGetNextFrameFailed) are disabled. - // The reason for adding this scheme is to prevent logs of - // kTryGetNextFrameFailed in the startup phase when some empty frames is - // expected and should not be seen as an error. - int empty_frame_credit_count_ = 0; - // Caches the value of DesktopCaptureOptions.allow_wgc_zero_hertz() in // StartCapture(). Adds 0Hz detection in ProcessFrame() when enabled which // adds complexity since memcmp() is performed on two successive frames. diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller.cc b/third_party/libwebrtc/modules/pacing/pacing_controller.cc index cd94c7bf3e5c0..a526fc136273c 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller.cc +++ b/third_party/libwebrtc/modules/pacing/pacing_controller.cc @@ -67,6 +67,8 @@ PacingController::PacingController(Clock* clock, IsEnabled(field_trials_, "WebRTC-Pacer-IgnoreTransportOverhead")), fast_retransmissions_( IsEnabled(field_trials_, "WebRTC-Pacer-FastRetransmissions")), + keyframe_flushing_( + IsEnabled(field_trials_, "WebRTC-Pacer-KeyframeFlushing")), transport_overhead_per_packet_(DataSize::Zero()), send_burst_interval_(TimeDelta::Zero()), last_timestamp_(clock_->CurrentTime()), @@ -188,6 +190,21 @@ void PacingController::EnqueuePacket(std::unique_ptr packet) { << "SetPacingRate must be called before InsertPacket."; RTC_CHECK(packet->packet_type()); + if (keyframe_flushing_ && + packet->packet_type() == RtpPacketMediaType::kVideo && + packet->is_key_frame() && packet->is_first_packet_of_frame() && + !packet_queue_.HasKeyframePackets(packet->Ssrc())) { + // First packet of a keyframe (and no keyframe packets currently in the + // queue). Flush any pending packets currently in the queue for that stream + // in order to get the new keyframe out as quickly as possible. + packet_queue_.RemovePacketsForSsrc(packet->Ssrc()); + absl::optional rtx_ssrc = + packet_sender_->GetRtxSsrcForMedia(packet->Ssrc()); + if (rtx_ssrc) { + packet_queue_.RemovePacketsForSsrc(*rtx_ssrc); + } + } + prober_.OnIncomingPacket(DataSize::Bytes(packet->payload_size())); const Timestamp now = CurrentTime(); diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller.h b/third_party/libwebrtc/modules/pacing/pacing_controller.h index 5b948373c0e5b..b0d802b48f536 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller.h +++ b/third_party/libwebrtc/modules/pacing/pacing_controller.h @@ -205,6 +205,7 @@ class PacingController { const bool pace_audio_; const bool ignore_transport_overhead_; const bool fast_retransmissions_; + const bool keyframe_flushing_; DataSize transport_overhead_per_packet_; TimeDelta send_burst_interval_; diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc b/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc index 688a3cc613525..2c5f8e9b07725 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc @@ -656,55 +656,55 @@ TEST_F(PacingControllerTest, Padding) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } - const TimeDelta actual_pace_time = clock_.CurrentTime() - start_time; - EXPECT_LE((actual_pace_time - expected_pace_time).Abs(), - PacingController::kMinSleepTime); - - // Pacing media happens at 2.5x, but padding was configured with 1.0x - // factor. We have to wait until the padding debt is gone before we start - // sending padding. - const TimeDelta time_to_padding_debt_free = - (expected_pace_time * kPaceMultiplier) - actual_pace_time; - clock_.AdvanceTime(time_to_padding_debt_free - - PacingController::kMinSleepTime); - pacer->ProcessPackets(); + const TimeDelta actual_pace_time = clock_.CurrentTime() - start_time; + EXPECT_LE((actual_pace_time - expected_pace_time).Abs(), + PacingController::kMinSleepTime); - // Send 10 padding packets. - const size_t kPaddingPacketsToSend = 10; - DataSize padding_sent = DataSize::Zero(); - size_t packets_sent = 0; - Timestamp first_send_time = Timestamp::MinusInfinity(); - Timestamp last_send_time = Timestamp::MinusInfinity(); - - EXPECT_CALL(callback_, SendPadding) - .Times(kPaddingPacketsToSend) - .WillRepeatedly([&](size_t target_size) { - ++packets_sent; - if (packets_sent < kPaddingPacketsToSend) { - // Don't count bytes of last packet, instead just - // use this as the time the last packet finished - // sending. - padding_sent += DataSize::Bytes(target_size); - } - if (first_send_time.IsInfinite()) { - first_send_time = clock_.CurrentTime(); - } else { - last_send_time = clock_.CurrentTime(); - } - return target_size; - }); - EXPECT_CALL(callback_, SendPacket(_, _, _, false, true)) - .Times(kPaddingPacketsToSend); + // Pacing media happens at 2.5x, but padding was configured with 1.0x + // factor. We have to wait until the padding debt is gone before we start + // sending padding. + const TimeDelta time_to_padding_debt_free = + (expected_pace_time * kPaceMultiplier) - actual_pace_time; + clock_.AdvanceTime(time_to_padding_debt_free - + PacingController::kMinSleepTime); + pacer->ProcessPackets(); - while (packets_sent < kPaddingPacketsToSend) { - AdvanceTimeUntil(pacer->NextSendTime()); - pacer->ProcessPackets(); - } + // Send 10 padding packets. + const size_t kPaddingPacketsToSend = 10; + DataSize padding_sent = DataSize::Zero(); + size_t packets_sent = 0; + Timestamp first_send_time = Timestamp::MinusInfinity(); + Timestamp last_send_time = Timestamp::MinusInfinity(); + + EXPECT_CALL(callback_, SendPadding) + .Times(kPaddingPacketsToSend) + .WillRepeatedly([&](size_t target_size) { + ++packets_sent; + if (packets_sent < kPaddingPacketsToSend) { + // Don't count bytes of last packet, instead just + // use this as the time the last packet finished + // sending. + padding_sent += DataSize::Bytes(target_size); + } + if (first_send_time.IsInfinite()) { + first_send_time = clock_.CurrentTime(); + } else { + last_send_time = clock_.CurrentTime(); + } + return target_size; + }); + EXPECT_CALL(callback_, SendPacket(_, _, _, false, true)) + .Times(kPaddingPacketsToSend); - // Verify rate of sent padding. - TimeDelta padding_duration = last_send_time - first_send_time; - DataRate padding_rate = padding_sent / padding_duration; - EXPECT_EQ(padding_rate, kTargetRate); + while (packets_sent < kPaddingPacketsToSend) { + AdvanceTimeUntil(pacer->NextSendTime()); + pacer->ProcessPackets(); + } + + // Verify rate of sent padding. + TimeDelta padding_duration = last_send_time - first_send_time; + DataRate padding_rate = padding_sent / padding_duration; + EXPECT_EQ(padding_rate, kTargetRate); } TEST_F(PacingControllerTest, NoPaddingBeforeNormalPacket) { @@ -1245,66 +1245,66 @@ TEST_F(PacingControllerTest, SkipsProbesWhenProcessIntervalTooLarge) { pacer->ProcessPackets(); } - // Probe at a very high rate. - std::vector probe_clusters = { - {.at_time = clock_.CurrentTime(), - .target_data_rate = DataRate::KilobitsPerSec(10000), // 10 Mbps, - .target_duration = TimeDelta::Millis(15), - .target_probe_count = 5, - .id = kProbeClusterId}}; - pacer->CreateProbeClusters(probe_clusters); - - // We need one packet to start the probe. - pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, - sequence_number++, - clock_.TimeInMilliseconds(), kPacketSize)); - const int packets_sent_before_probe = packet_sender.packets_sent(); - AdvanceTimeUntil(pacer->NextSendTime()); - pacer->ProcessPackets(); - EXPECT_EQ(packet_sender.packets_sent(), packets_sent_before_probe + 1); + // Probe at a very high rate. + std::vector probe_clusters = { + {.at_time = clock_.CurrentTime(), + .target_data_rate = DataRate::KilobitsPerSec(10000), // 10 Mbps, + .target_duration = TimeDelta::Millis(15), + .target_probe_count = 5, + .id = kProbeClusterId}}; + pacer->CreateProbeClusters(probe_clusters); - // Figure out how long between probe packets. - Timestamp start_time = clock_.CurrentTime(); - AdvanceTimeUntil(pacer->NextSendTime()); - TimeDelta time_between_probes = clock_.CurrentTime() - start_time; - // Advance that distance again + 1ms. - clock_.AdvanceTime(time_between_probes); + // We need one packet to start the probe. + pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, + sequence_number++, + clock_.TimeInMilliseconds(), kPacketSize)); + const int packets_sent_before_probe = packet_sender.packets_sent(); + AdvanceTimeUntil(pacer->NextSendTime()); + pacer->ProcessPackets(); + EXPECT_EQ(packet_sender.packets_sent(), packets_sent_before_probe + 1); - // Send second probe packet. - pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, - sequence_number++, - clock_.TimeInMilliseconds(), kPacketSize)); - pacer->ProcessPackets(); - EXPECT_EQ(packet_sender.packets_sent(), packets_sent_before_probe + 2); - PacedPacketInfo last_pacing_info = packet_sender.last_pacing_info(); - EXPECT_EQ(last_pacing_info.probe_cluster_id, kProbeClusterId); - - // We're exactly where we should be for the next probe. - const Timestamp probe_time = clock_.CurrentTime(); - EXPECT_EQ(pacer->NextSendTime(), clock_.CurrentTime()); - - BitrateProberConfig probing_config(&trials); - EXPECT_GT(probing_config.max_probe_delay.Get(), TimeDelta::Zero()); - // Advance to within max probe delay, should still return same target. - clock_.AdvanceTime(probing_config.max_probe_delay.Get()); - EXPECT_EQ(pacer->NextSendTime(), probe_time); - - // Too high probe delay, drop it! - clock_.AdvanceTime(TimeDelta::Micros(1)); - - int packets_sent_before_timeout = packet_sender.total_packets_sent(); - // Expected next process time is unchanged, but calling should not - // generate new packets. - EXPECT_EQ(pacer->NextSendTime(), probe_time); - pacer->ProcessPackets(); - EXPECT_EQ(packet_sender.total_packets_sent(), packets_sent_before_timeout); + // Figure out how long between probe packets. + Timestamp start_time = clock_.CurrentTime(); + AdvanceTimeUntil(pacer->NextSendTime()); + TimeDelta time_between_probes = clock_.CurrentTime() - start_time; + // Advance that distance again + 1ms. + clock_.AdvanceTime(time_between_probes); + + // Send second probe packet. + pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, + sequence_number++, + clock_.TimeInMilliseconds(), kPacketSize)); + pacer->ProcessPackets(); + EXPECT_EQ(packet_sender.packets_sent(), packets_sent_before_probe + 2); + PacedPacketInfo last_pacing_info = packet_sender.last_pacing_info(); + EXPECT_EQ(last_pacing_info.probe_cluster_id, kProbeClusterId); + + // We're exactly where we should be for the next probe. + const Timestamp probe_time = clock_.CurrentTime(); + EXPECT_EQ(pacer->NextSendTime(), clock_.CurrentTime()); + + BitrateProberConfig probing_config(&trials); + EXPECT_GT(probing_config.max_probe_delay.Get(), TimeDelta::Zero()); + // Advance to within max probe delay, should still return same target. + clock_.AdvanceTime(probing_config.max_probe_delay.Get()); + EXPECT_EQ(pacer->NextSendTime(), probe_time); + + // Too high probe delay, drop it! + clock_.AdvanceTime(TimeDelta::Micros(1)); + + int packets_sent_before_timeout = packet_sender.total_packets_sent(); + // Expected next process time is unchanged, but calling should not + // generate new packets. + EXPECT_EQ(pacer->NextSendTime(), probe_time); + pacer->ProcessPackets(); + EXPECT_EQ(packet_sender.total_packets_sent(), packets_sent_before_timeout); - // Next packet sent is not part of probe. - AdvanceTimeUntil(pacer->NextSendTime()); - pacer->ProcessPackets(); - const int expected_probe_id = PacedPacketInfo::kNotAProbe; - EXPECT_EQ(packet_sender.last_pacing_info().probe_cluster_id, - expected_probe_id); + // Next packet sent is not part of probe. + AdvanceTimeUntil(pacer->NextSendTime()); + pacer->ProcessPackets(); + const int expected_probe_id = PacedPacketInfo::kNotAProbe; + EXPECT_EQ(packet_sender.last_pacing_info().probe_cluster_id, + expected_probe_id); } TEST_F(PacingControllerTest, ProbingWithPaddingSupport) { @@ -2255,5 +2255,44 @@ TEST_F(PacingControllerTest, DoesNotPadIfProcessThreadIsBorked) { EXPECT_LE(callback.padding_sent(), kMaxPadding.bytes()); } +TEST_F(PacingControllerTest, FlushesPacketsOnKeyFrames) { + const uint32_t kSsrc = 12345; + const uint32_t kRtxSsrc = 12346; + + const test::ExplicitKeyValueConfig trials( + "WebRTC-Pacer-KeyframeFlushing/Enabled/"); + auto pacer = std::make_unique(&clock_, &callback_, trials); + EXPECT_CALL(callback_, GetRtxSsrcForMedia(kSsrc)) + .WillRepeatedly(Return(kRtxSsrc)); + pacer->SetPacingRates(kTargetRate, DataRate::Zero()); + + // Enqueue a video packet and a retransmission of that video stream. + pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, kSsrc, + /*sequence_number=*/1, /*capture_time=*/1, + /*size_bytes=*/100)); + pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kRetransmission, + kRtxSsrc, + /*sequence_number=*/10, /*capture_time=*/1, + /*size_bytes=*/100)); + EXPECT_EQ(pacer->QueueSizePackets(), 2u); + + // Enqueue the first packet of a keyframe for said stream. + auto packet = BuildPacket(RtpPacketMediaType::kVideo, kSsrc, + /*sequence_number=*/2, /*capture_time=*/2, + /*size_bytes=*/1000); + packet->set_is_key_frame(true); + packet->set_first_packet_of_frame(true); + pacer->EnqueuePacket(std::move(packet)); + + // Only they new keyframe packet should be left in the queue. + EXPECT_EQ(pacer->QueueSizePackets(), 1u); + + EXPECT_CALL(callback_, SendPacket(kSsrc, /*sequence_number=*/2, + /*timestamp=*/2, /*is_retrnamission=*/false, + /*is_padding=*/false)); + AdvanceTimeUntil(pacer->NextSendTime()); + pacer->ProcessPackets(); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/modules/pacing/packet_router.cc b/third_party/libwebrtc/modules/pacing/packet_router.cc index b28d9776dc909..85490ef82d977 100644 --- a/third_party/libwebrtc/modules/pacing/packet_router.cc +++ b/third_party/libwebrtc/modules/pacing/packet_router.cc @@ -19,12 +19,10 @@ #include "absl/types/optional.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_packet.h" -#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/system/unused.h" -#include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" namespace webrtc { @@ -37,6 +35,7 @@ PacketRouter::PacketRouter(uint16_t start_transport_seq) transport_seq_(start_transport_seq) {} PacketRouter::~PacketRouter() { + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(send_modules_map_.empty()); RTC_DCHECK(send_modules_list_.empty()); RTC_DCHECK(rtcp_feedback_senders_.empty()); @@ -47,7 +46,7 @@ PacketRouter::~PacketRouter() { void PacketRouter::AddSendRtpModule(RtpRtcpInterface* rtp_module, bool remb_candidate) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); AddSendRtpModuleToMap(rtp_module, rtp_module->SSRC()); if (absl::optional rtx_ssrc = rtp_module->RtxSsrc()) { @@ -68,6 +67,7 @@ void PacketRouter::AddSendRtpModule(RtpRtcpInterface* rtp_module, void PacketRouter::AddSendRtpModuleToMap(RtpRtcpInterface* rtp_module, uint32_t ssrc) { + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(send_modules_map_.find(ssrc) == send_modules_map_.end()); // Signal to module that the pacer thread is attached and can send packets. @@ -86,6 +86,7 @@ void PacketRouter::AddSendRtpModuleToMap(RtpRtcpInterface* rtp_module, } void PacketRouter::RemoveSendRtpModuleFromMap(uint32_t ssrc) { + RTC_DCHECK_RUN_ON(&thread_checker_); auto it = send_modules_map_.find(ssrc); RTC_DCHECK(it != send_modules_map_.end()); send_modules_list_.remove(it->second); @@ -93,7 +94,7 @@ void PacketRouter::RemoveSendRtpModuleFromMap(uint32_t ssrc) { } void PacketRouter::RemoveSendRtpModule(RtpRtcpInterface* rtp_module) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); MaybeRemoveRembModuleCandidate(rtp_module, /* media_sender = */ true); RemoveSendRtpModuleFromMap(rtp_module->SSRC()); @@ -112,7 +113,7 @@ void PacketRouter::RemoveSendRtpModule(RtpRtcpInterface* rtp_module) { void PacketRouter::AddReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender, bool remb_candidate) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(std::find(rtcp_feedback_senders_.begin(), rtcp_feedback_senders_.end(), rtcp_sender) == rtcp_feedback_senders_.end()); @@ -126,7 +127,7 @@ void PacketRouter::AddReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender, void PacketRouter::RemoveReceiveRtpModule( RtcpFeedbackSenderInterface* rtcp_sender) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); MaybeRemoveRembModuleCandidate(rtcp_sender, /* media_sender = */ false); auto it = std::find(rtcp_feedback_senders_.begin(), rtcp_feedback_senders_.end(), rtcp_sender); @@ -136,11 +137,11 @@ void PacketRouter::RemoveReceiveRtpModule( void PacketRouter::SendPacket(std::unique_ptr packet, const PacedPacketInfo& cluster_info) { + RTC_DCHECK_RUN_ON(&thread_checker_); TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("webrtc"), "PacketRouter::SendPacket", "sequence_number", packet->SequenceNumber(), "rtp_timestamp", packet->Timestamp()); - MutexLock lock(&modules_mutex_); // With the new pacer code path, transport sequence numbers are only set here, // on the pacer thread. Therefore we don't need atomics/synchronization. bool assign_transport_sequence_number = @@ -184,7 +185,7 @@ void PacketRouter::SendPacket(std::unique_ptr packet, } std::vector> PacketRouter::FetchFec() { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); std::vector> fec_packets = std::move(pending_fec_packets_); pending_fec_packets_.clear(); @@ -193,10 +194,10 @@ std::vector> PacketRouter::FetchFec() { std::vector> PacketRouter::GeneratePadding( DataSize size) { + RTC_DCHECK_RUN_ON(&thread_checker_); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("webrtc"), "PacketRouter::GeneratePadding", "bytes", size.bytes()); - MutexLock lock(&modules_mutex_); // First try on the last rtp module to have sent media. This increases the // the chance that any payload based padding will be useful as it will be // somewhat distributed over modules according the packet rate, even if it @@ -238,7 +239,7 @@ std::vector> PacketRouter::GeneratePadding( void PacketRouter::OnAbortedRetransmissions( uint32_t ssrc, rtc::ArrayView sequence_numbers) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); auto it = send_modules_map_.find(ssrc); if (it != send_modules_map_.end()) { it->second->OnAbortedRetransmissions(sequence_numbers); @@ -246,7 +247,7 @@ void PacketRouter::OnAbortedRetransmissions( } absl::optional PacketRouter::GetRtxSsrcForMedia(uint32_t ssrc) const { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); auto it = send_modules_map_.find(ssrc); if (it != send_modules_map_.end() && it->second->SSRC() == ssrc) { // A module is registered with the given SSRC, and that SSRC is the main @@ -257,12 +258,12 @@ absl::optional PacketRouter::GetRtxSsrcForMedia(uint32_t ssrc) const { } uint16_t PacketRouter::CurrentTransportSequenceNumber() const { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); return transport_seq_ & 0xFFFF; } void PacketRouter::SendRemb(int64_t bitrate_bps, std::vector ssrcs) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); if (!active_remb_module_) { return; @@ -275,7 +276,7 @@ void PacketRouter::SendRemb(int64_t bitrate_bps, std::vector ssrcs) { void PacketRouter::SendCombinedRtcpPacket( std::vector> packets) { - MutexLock lock(&modules_mutex_); + RTC_DCHECK_RUN_ON(&thread_checker_); // Prefer send modules. for (RtpRtcpInterface* rtp_module : send_modules_list_) { @@ -308,6 +309,7 @@ void PacketRouter::AddRembModuleCandidate( void PacketRouter::MaybeRemoveRembModuleCandidate( RtcpFeedbackSenderInterface* candidate_module, bool media_sender) { + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(candidate_module); std::vector& candidates = media_sender ? sender_remb_candidates_ : receiver_remb_candidates_; @@ -325,12 +327,14 @@ void PacketRouter::MaybeRemoveRembModuleCandidate( } void PacketRouter::UnsetActiveRembModule() { + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_CHECK(active_remb_module_); active_remb_module_->UnsetRemb(); active_remb_module_ = nullptr; } void PacketRouter::DetermineActiveRembModule() { + RTC_DCHECK_RUN_ON(&thread_checker_); // Sender modules take precedence over receiver modules, because SRs (sender // reports) are sent more frequently than RR (receiver reports). // When adding the first sender module, we should change the active REMB diff --git a/third_party/libwebrtc/modules/pacing/packet_router.h b/third_party/libwebrtc/modules/pacing/packet_router.h index 68b82c6bd42ea..805f4221123f1 100644 --- a/third_party/libwebrtc/modules/pacing/packet_router.h +++ b/third_party/libwebrtc/modules/pacing/packet_router.h @@ -20,12 +20,12 @@ #include #include +#include "api/sequence_checker.h" #include "api/transport/network_types.h" #include "modules/pacing/pacing_controller.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_packet.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" namespace webrtc { @@ -74,45 +74,40 @@ class PacketRouter : public PacingController::PacketSender { private: void AddRembModuleCandidate(RtcpFeedbackSenderInterface* candidate_module, - bool media_sender) - RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); + bool media_sender); void MaybeRemoveRembModuleCandidate( RtcpFeedbackSenderInterface* candidate_module, - bool media_sender) RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); - void UnsetActiveRembModule() RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); - void DetermineActiveRembModule() RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); - void AddSendRtpModuleToMap(RtpRtcpInterface* rtp_module, uint32_t ssrc) - RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); - void RemoveSendRtpModuleFromMap(uint32_t ssrc) - RTC_EXCLUSIVE_LOCKS_REQUIRED(modules_mutex_); - - mutable Mutex modules_mutex_; + bool media_sender); + void UnsetActiveRembModule(); + void DetermineActiveRembModule(); + void AddSendRtpModuleToMap(RtpRtcpInterface* rtp_module, uint32_t ssrc); + void RemoveSendRtpModuleFromMap(uint32_t ssrc); + + SequenceChecker thread_checker_; // Ssrc to RtpRtcpInterface module; std::unordered_map send_modules_map_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); std::list send_modules_list_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); // The last module used to send media. - RtpRtcpInterface* last_send_module_ RTC_GUARDED_BY(modules_mutex_); + RtpRtcpInterface* last_send_module_ RTC_GUARDED_BY(thread_checker_); // Rtcp modules of the rtp receivers. std::vector rtcp_feedback_senders_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); // Candidates for the REMB module can be RTP sender/receiver modules, with // the sender modules taking precedence. std::vector sender_remb_candidates_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); std::vector receiver_remb_candidates_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); RtcpFeedbackSenderInterface* active_remb_module_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); - uint64_t transport_seq_ RTC_GUARDED_BY(modules_mutex_); + uint64_t transport_seq_ RTC_GUARDED_BY(thread_checker_); - // TODO(bugs.webrtc.org/10809): Replace lock with a sequence checker once the - // process thread is gone. std::vector> pending_fec_packets_ - RTC_GUARDED_BY(modules_mutex_); + RTC_GUARDED_BY(thread_checker_); }; } // namespace webrtc #endif // MODULES_PACING_PACKET_ROUTER_H_ diff --git a/third_party/libwebrtc/modules/pacing/packet_router_unittest.cc b/third_party/libwebrtc/modules/pacing/packet_router_unittest.cc index 65b2ad24d6e0d..76d14c9dce709 100644 --- a/third_party/libwebrtc/modules/pacing/packet_router_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/packet_router_unittest.cc @@ -75,7 +75,6 @@ TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_GeneratePadding) { EXPECT_TRUE(packet_router_.GeneratePadding(bytes).empty()); } - TEST_F(PacketRouterTest, Sanity_NoModuleRegistered_SendRemb) { const std::vector ssrcs = {1, 2, 3}; constexpr uint32_t bitrate_bps = 10000; diff --git a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.cc b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.cc index 0c285c463a782..ea211ea6830fe 100644 --- a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.cc +++ b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.cc @@ -50,10 +50,13 @@ DataSize PrioritizedPacketQueue::QueuedPacket::PacketSize() const { } PrioritizedPacketQueue::StreamQueue::StreamQueue(Timestamp creation_time) - : last_enqueue_time_(creation_time) {} + : last_enqueue_time_(creation_time), num_keyframe_packets_(0) {} bool PrioritizedPacketQueue::StreamQueue::EnqueuePacket(QueuedPacket packet, int priority_level) { + if (packet.packet->is_key_frame()) { + ++num_keyframe_packets_; + } bool first_packet_at_level = packets_[priority_level].empty(); packets_[priority_level].push_back(std::move(packet)); return first_packet_at_level; @@ -64,6 +67,10 @@ PrioritizedPacketQueue::StreamQueue::DequeuePacket(int priority_level) { RTC_DCHECK(!packets_[priority_level].empty()); QueuedPacket packet = std::move(packets_[priority_level].front()); packets_[priority_level].pop_front(); + if (packet.packet->is_key_frame()) { + RTC_DCHECK_GT(num_keyframe_packets_, 0); + --num_keyframe_packets_; + } return packet; } @@ -98,6 +105,7 @@ PrioritizedPacketQueue::StreamQueue::DequeueAll() { for (int i = 0; i < kNumPriorityLevels; ++i) { packets_by_prio[i].swap(packets_[i]); } + num_keyframe_packets_ = 0; return packets_by_prio; } @@ -292,6 +300,14 @@ void PrioritizedPacketQueue::RemovePacketsForSsrc(uint32_t ssrc) { } } +bool PrioritizedPacketQueue::HasKeyframePackets(uint32_t ssrc) const { + auto it = streams_.find(ssrc); + if (it != streams_.end()) { + return it->second->has_keyframe_packets(); + } + return false; +} + void PrioritizedPacketQueue::DequeuePacketInternal(QueuedPacket& packet) { --size_packets_; RTC_DCHECK(packet.packet->packet_type().has_value()); diff --git a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.h b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.h index 364b53af11ced..935c5300274c8 100644 --- a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.h +++ b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue.h @@ -85,6 +85,10 @@ class PrioritizedPacketQueue { // Remove any packets matching the given SSRC. void RemovePacketsForSsrc(uint32_t ssrc); + // Checks if the queue for the given SSRC has original (retransmissions not + // counted) video packets containing keyframe data. + bool HasKeyframePackets(uint32_t ssrc) const; + private: static constexpr int kNumPriorityLevels = 4; @@ -118,12 +122,14 @@ class PrioritizedPacketQueue { bool IsEmpty() const; Timestamp LeadingPacketEnqueueTime(int priority_level) const; Timestamp LastEnqueueTime() const; + bool has_keyframe_packets() const { return num_keyframe_packets_ > 0; } std::array, kNumPriorityLevels> DequeueAll(); private: std::deque packets_[kNumPriorityLevels]; Timestamp last_enqueue_time_; + int num_keyframe_packets_; }; // Remove the packet from the internal state, e.g. queue time / size etc. diff --git a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc index 964051c0c7017..9ed19642c7420 100644 --- a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc @@ -27,12 +27,14 @@ constexpr int kDefaultPayloadSize = 789; std::unique_ptr CreatePacket(RtpPacketMediaType type, uint16_t sequence_number, - uint32_t ssrc = kDefaultSsrc) { + uint32_t ssrc = kDefaultSsrc, + bool is_key_frame = false) { auto packet = std::make_unique(/*extensions=*/nullptr); packet->set_packet_type(type); packet->SetSsrc(ssrc); packet->SetSequenceNumber(sequence_number); packet->SetPayloadSize(kDefaultPayloadSize); + packet->set_is_key_frame(is_key_frame); return packet; } @@ -360,4 +362,55 @@ TEST(PrioritizedPacketQueue, ClearPacketsAffectsOnlySpecifiedSsrc) { EXPECT_TRUE(queue.Empty()); } +TEST(PrioritizedPacketQueue, ReportsKeyframePackets) { + Timestamp now = Timestamp::Zero(); + PrioritizedPacketQueue queue(now); + const uint32_t kVideoSsrc1 = 1234; + const uint32_t kVideoSsrc2 = 2345; + + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); + + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/1, + kVideoSsrc1, /*is_key_frame=*/true)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/11, + kVideoSsrc2, /*is_key_frame=*/false)); + + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); + + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2, + kVideoSsrc1, /*is_key_frame=*/true)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/12, + kVideoSsrc2, /*is_key_frame=*/true)); + + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); + + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3, + kVideoSsrc1, /*is_key_frame=*/false)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/13, + kVideoSsrc2, /*is_key_frame=*/true)); + + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); + + EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 11); + + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); + + EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 12); + + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); + + queue.RemovePacketsForSsrc(kVideoSsrc2); + + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); + EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); +} + } // namespace webrtc diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc index 2747760eff3b6..b5dfdd466a933 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc @@ -40,7 +40,6 @@ TaskQueuePacedSender::TaskQueuePacedSender( Clock* clock, PacingController::PacketSender* packet_sender, const FieldTrialsView& field_trials, - TaskQueueFactory* task_queue_factory, TimeDelta max_hold_back_window, int max_hold_back_window_in_packets, absl::optional burst_interval) @@ -54,7 +53,7 @@ TaskQueuePacedSender::TaskQueuePacedSender( is_shutdown_(false), packet_size_(/*alpha=*/0.95), include_overhead_(false), - task_queue_(field_trials, "TaskQueuePacedSender", task_queue_factory) { + task_queue_(TaskQueueBase::Current()) { RTC_DCHECK_GE(max_hold_back_window_, PacingController::kMinSleepTime); // There are multiple field trials that can affect burst. If multiple bursts // are specified we pick the largest of the values. @@ -70,70 +69,52 @@ TaskQueuePacedSender::TaskQueuePacedSender( } TaskQueuePacedSender::~TaskQueuePacedSender() { - // Post an immediate task to mark the queue as shutting down. - // The rtc::TaskQueue destructor will wait for pending tasks to - // complete before continuing. - task_queue_.RunOrPost([&]() { - RTC_DCHECK_RUN_ON(&task_queue_); - is_shutdown_ = true; - }); + RTC_DCHECK_RUN_ON(task_queue_); + is_shutdown_ = true; } void TaskQueuePacedSender::EnsureStarted() { - task_queue_.RunOrPost([this]() { - RTC_DCHECK_RUN_ON(&task_queue_); - is_started_ = true; - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + is_started_ = true; + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::CreateProbeClusters( std::vector probe_cluster_configs) { - task_queue_.RunOrPost( - [this, probe_cluster_configs = std::move(probe_cluster_configs)]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.CreateProbeClusters(probe_cluster_configs); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.CreateProbeClusters(probe_cluster_configs); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::Pause() { - task_queue_.RunOrPost([this]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.Pause(); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.Pause(); } void TaskQueuePacedSender::Resume() { - task_queue_.RunOrPost([this]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.Resume(); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.Resume(); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::SetCongested(bool congested) { - task_queue_.RunOrPost([this, congested]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.SetCongested(congested); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetCongested(congested); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::SetPacingRates(DataRate pacing_rate, DataRate padding_rate) { - task_queue_.RunOrPost([this, pacing_rate, padding_rate]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.SetPacingRates(pacing_rate, padding_rate); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetPacingRates(pacing_rate, padding_rate); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::EnqueuePackets( std::vector> packets) { - task_queue_.TaskQueueForPost()->PostTask(task_queue_.MaybeSafeTask( - safety_.flag(), [this, packets = std::move(packets)]() mutable { - RTC_DCHECK_RUN_ON(&task_queue_); + task_queue_->PostTask( + SafeTask(safety_.flag(), [this, packets = std::move(packets)]() mutable { + RTC_DCHECK_RUN_ON(task_queue_); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webrtc"), "TaskQueuePacedSender::EnqueuePackets"); for (auto& packet : packets) { @@ -155,45 +136,36 @@ void TaskQueuePacedSender::EnqueuePackets( } void TaskQueuePacedSender::RemovePacketsForSsrc(uint32_t ssrc) { - task_queue_.TaskQueueForPost()->PostTask( - task_queue_.MaybeSafeTask(safety_.flag(), [this, ssrc] { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.RemovePacketsForSsrc(ssrc); - MaybeProcessPackets(Timestamp::MinusInfinity()); - })); + task_queue_->PostTask(SafeTask(safety_.flag(), [this, ssrc] { + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.RemovePacketsForSsrc(ssrc); + MaybeProcessPackets(Timestamp::MinusInfinity()); + })); } void TaskQueuePacedSender::SetAccountForAudioPackets(bool account_for_audio) { - task_queue_.RunOrPost([this, account_for_audio]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.SetAccountForAudioPackets(account_for_audio); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetAccountForAudioPackets(account_for_audio); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::SetIncludeOverhead() { - task_queue_.RunOrPost([this]() { - RTC_DCHECK_RUN_ON(&task_queue_); - include_overhead_ = true; - pacing_controller_.SetIncludeOverhead(); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + include_overhead_ = true; + pacing_controller_.SetIncludeOverhead(); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::SetTransportOverhead(DataSize overhead_per_packet) { - task_queue_.RunOrPost([this, overhead_per_packet]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.SetTransportOverhead(overhead_per_packet); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetTransportOverhead(overhead_per_packet); + MaybeProcessPackets(Timestamp::MinusInfinity()); } void TaskQueuePacedSender::SetQueueTimeLimit(TimeDelta limit) { - task_queue_.RunOrPost([this, limit]() { - RTC_DCHECK_RUN_ON(&task_queue_); - pacing_controller_.SetQueueTimeLimit(limit); - MaybeProcessPackets(Timestamp::MinusInfinity()); - }); + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetQueueTimeLimit(limit); + MaybeProcessPackets(Timestamp::MinusInfinity()); } TimeDelta TaskQueuePacedSender::ExpectedQueueTime() const { @@ -224,13 +196,13 @@ TimeDelta TaskQueuePacedSender::OldestPacketWaitTime() const { } void TaskQueuePacedSender::OnStatsUpdated(const Stats& stats) { - MutexLock lock(&stats_mutex_); + RTC_DCHECK_RUN_ON(task_queue_); current_stats_ = stats; } void TaskQueuePacedSender::MaybeProcessPackets( Timestamp scheduled_process_time) { - RTC_DCHECK_RUN_ON(&task_queue_); + RTC_DCHECK_RUN_ON(task_queue_); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("webrtc"), "TaskQueuePacedSender::MaybeProcessPackets"); @@ -294,8 +266,8 @@ void TaskQueuePacedSender::MaybeProcessPackets( if (next_process_time_.IsMinusInfinity() || next_process_time_ > next_send_time) { // Prefer low precision if allowed and not probing. - task_queue_.TaskQueueForDelayedTasks()->PostDelayedHighPrecisionTask( - task_queue_.MaybeSafeTask( + task_queue_->PostDelayedHighPrecisionTask( + SafeTask( safety_.flag(), [this, next_send_time]() { MaybeProcessPackets(next_send_time); }), time_to_next_process.RoundUpTo(TimeDelta::Millis(1))); @@ -314,7 +286,7 @@ void TaskQueuePacedSender::UpdateStats() { } TaskQueuePacedSender::Stats TaskQueuePacedSender::GetStats() const { - MutexLock lock(&stats_mutex_); + RTC_DCHECK_RUN_ON(task_queue_); return current_stats_; } diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h index 4d5169561e964..7bb00572d0019 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h @@ -20,14 +20,13 @@ #include "absl/types/optional.h" #include "api/field_trials_view.h" #include "api/sequence_checker.h" -#include "api/task_queue/task_queue_factory.h" +#include "api/task_queue/pending_task_safety_flag.h" #include "api/units/data_size.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "modules/pacing/pacing_controller.h" #include "modules/pacing/rtp_packet_pacer.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "modules/utility/maybe_worker_thread.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/numerics/exp_filter.h" #include "rtc_base/thread_annotations.h" @@ -50,11 +49,13 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender { // a packet "debt" that correspond to approximately the send rate during the // specified interval. This greatly reduced wake ups by not pacing packets // within the allowed burst budget. + // + // The taskqueue used when constructing a TaskQueuePacedSender will also be + // used for pacing. TaskQueuePacedSender( Clock* clock, PacingController::PacketSender* packet_sender, const FieldTrialsView& field_trials, - TaskQueueFactory* task_queue_factory, TimeDelta max_hold_back_window, int max_hold_back_window_in_packets, absl::optional burst_interval = absl::nullopt); @@ -178,13 +179,10 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender { rtc::ExpFilter packet_size_ RTC_GUARDED_BY(task_queue_); bool include_overhead_ RTC_GUARDED_BY(task_queue_); - // TODO(webrtc:14502): Remove stats_mutex_ when pacer runs on the worker - // thread. - mutable Mutex stats_mutex_; - Stats current_stats_ RTC_GUARDED_BY(stats_mutex_); + Stats current_stats_ RTC_GUARDED_BY(task_queue_); ScopedTaskSafety safety_; - MaybeWorkerThread task_queue_; + TaskQueueBase* task_queue_; }; } // namespace webrtc #endif // MODULES_PACING_TASK_QUEUE_PACED_SENDER_H_ diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc index a8a7b65ef4e9f..54347493e7085 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc @@ -118,35 +118,11 @@ std::vector> GeneratePackets( return packets; } -constexpr char kSendPacketOnWorkerThreadFieldTrialDisabled[] = - "WebRTC-SendPacketsOnWorkerThread/Disabled/"; - -std::vector ParameterizedFieldTrials() { - return {{""}, {kSendPacketOnWorkerThreadFieldTrialDisabled}}; -} - -bool UsingWorkerThread(absl::string_view field_trials) { - return field_trials.find(kSendPacketOnWorkerThreadFieldTrialDisabled) == - std::string::npos; -} - -class TaskQueuePacedSenderTest - : public ::testing::TestWithParam {}; - -INSTANTIATE_TEST_SUITE_P(TaskQueuePacedSenderTest, - TaskQueuePacedSenderTest, - testing::ValuesIn(ParameterizedFieldTrials()), - [](const testing::TestParamInfo& info) { - return UsingWorkerThread(info.param) ? "UsingWt" - : "OwnedTQ"; - }); - -TEST_P(TaskQueuePacedSenderTest, PacesPackets) { +TEST(TaskQueuePacedSenderTest, PacesPackets) { GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -170,7 +146,7 @@ TEST_P(TaskQueuePacedSenderTest, PacesPackets) { if (packets_sent == kPacketsToSend) { end_time = time_controller.GetClock()->CurrentTime(); } - EXPECT_EQ(sequence_checker.IsCurrent(), UsingWorkerThread(GetParam())); + EXPECT_TRUE(sequence_checker.IsCurrent()); }); const Timestamp start_time = time_controller.GetClock()->CurrentTime(); @@ -184,12 +160,12 @@ TEST_P(TaskQueuePacedSenderTest, PacesPackets) { } // Same test as above, but with 0.5s of burst applied. -TEST_P(TaskQueuePacedSenderTest, PacesPacketsWithBurst) { +TEST(TaskQueuePacedSenderTest, PacesPacketsWithBurst) { GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback, // Half a second of bursting. @@ -215,7 +191,7 @@ TEST_P(TaskQueuePacedSenderTest, PacesPacketsWithBurst) { if (packets_sent == kPacketsToSend) { end_time = time_controller.GetClock()->CurrentTime(); } - EXPECT_EQ(sequence_checker.IsCurrent(), UsingWorkerThread(GetParam())); + EXPECT_TRUE(sequence_checker.IsCurrent()); }); const Timestamp start_time = time_controller.GetClock()->CurrentTime(); @@ -230,12 +206,12 @@ TEST_P(TaskQueuePacedSenderTest, PacesPacketsWithBurst) { EXPECT_NEAR((end_time - start_time).ms(), 500.0, 50.0); } -TEST_P(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) { +TEST(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) { GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -284,12 +260,12 @@ TEST_P(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) { 1.0); } -TEST_P(TaskQueuePacedSenderTest, SendsAudioImmediately) { +TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) { GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -316,13 +292,13 @@ TEST_P(TaskQueuePacedSenderTest, SendsAudioImmediately) { ::testing::Mock::VerifyAndClearExpectations(&packet_router); } -TEST_P(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) { +TEST(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) { const TimeDelta kCoalescingWindow = TimeDelta::Millis(5); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + kCoalescingWindow, TaskQueuePacedSender::kNoPacketHoldback); @@ -353,13 +329,13 @@ TEST_P(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) { ::testing::Mock::VerifyAndClearExpectations(&packet_router); } -TEST_P(TaskQueuePacedSenderTest, ProbingOverridesCoalescingWindow) { +TEST(TaskQueuePacedSenderTest, ProbingOverridesCoalescingWindow) { const TimeDelta kCoalescingWindow = TimeDelta::Millis(5); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + kCoalescingWindow, TaskQueuePacedSender::kNoPacketHoldback); @@ -390,13 +366,13 @@ TEST_P(TaskQueuePacedSenderTest, ProbingOverridesCoalescingWindow) { time_controller.AdvanceTime(kCoalescingWindow - TimeDelta::Millis(1)); } -TEST_P(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) { +TEST(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) { ScopedKeyValueConfig trials( - GetParam() + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:1ms/"); + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:1ms/"); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -461,15 +437,15 @@ TEST_P(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) { time_controller.AdvanceTime(TimeDelta::Millis(2)); } -TEST_P(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) { +TEST(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) { // Set min_probe_delta to be less than kMinSleepTime (1ms). const TimeDelta kMinProbeDelta = TimeDelta::Micros(200); ScopedKeyValueConfig trials( - GetParam() + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:200us/"); + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:200us/"); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -523,15 +499,15 @@ TEST_P(TaskQueuePacedSenderTest, NoMinSleepTimeWhenProbing) { EXPECT_EQ(data_sent, DataSize::Bytes(1) + kPacketSize + 4 * kMinProbeSize); } -TEST_P(TaskQueuePacedSenderTest, PacketBasedCoalescing) { +TEST(TaskQueuePacedSenderTest, PacketBasedCoalescing) { const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(10); const int kPacketBasedHoldback = 5; GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + kFixedCoalescingWindow, kPacketBasedHoldback); // Set rates so one packet adds one ms of buffer level. @@ -573,15 +549,15 @@ TEST_P(TaskQueuePacedSenderTest, PacketBasedCoalescing) { time_controller.AdvanceTime(TimeDelta::Millis(1)); } -TEST_P(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) { +TEST(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) { const TimeDelta kFixedCoalescingWindow = TimeDelta::Millis(2); const int kPacketBasedHoldback = 5; GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + kFixedCoalescingWindow, kPacketBasedHoldback); // Set rates so one packet adds one ms of buffer level. @@ -620,15 +596,15 @@ TEST_P(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) { time_controller.AdvanceTime(kFixedCoalescingWindow); } -TEST_P(TaskQueuePacedSenderTest, ProbingStopDuringSendLoop) { +TEST(TaskQueuePacedSenderTest, ProbingStopDuringSendLoop) { // Set a low `min_probe_delta` to let probing finish during send loop. ScopedKeyValueConfig trials( - GetParam() + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:100us/"); + "WebRTC-Bwe-ProbingBehavior/min_probe_delta:100us/"); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); MockPacketRouter packet_router; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -670,13 +646,13 @@ TEST_P(TaskQueuePacedSenderTest, ProbingStopDuringSendLoop) { time_controller.AdvanceTime(kPacketsPacedTime + TimeDelta::Millis(1)); } -TEST_P(TaskQueuePacedSenderTest, PostedPacketsNotSendFromRemovePacketsForSsrc) { +TEST(TaskQueuePacedSenderTest, PostedPacketsNotSendFromRemovePacketsForSsrc) { static constexpr Timestamp kStartTime = Timestamp::Millis(1234); GlobalSimulatedTimeController time_controller(kStartTime); - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; MockPacketRouter packet_router; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); @@ -712,13 +688,13 @@ TEST_P(TaskQueuePacedSenderTest, PostedPacketsNotSendFromRemovePacketsForSsrc) { EXPECT_EQ(pacer.ExpectedQueueTime(), TimeDelta::Zero()); } -TEST_P(TaskQueuePacedSenderTest, Stats) { +TEST(TaskQueuePacedSenderTest, Stats) { static constexpr Timestamp kStartTime = Timestamp::Millis(1234); GlobalSimulatedTimeController time_controller(kStartTime); MockPacketRouter packet_router; - ScopedKeyValueConfig trials(GetParam()); + ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, - time_controller.GetTaskQueueFactory(), + PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/BUILD.gn b/third_party/libwebrtc/modules/remote_bitrate_estimator/BUILD.gn index 9d8f9bbc29e6c..5142c04ef0981 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/BUILD.gn +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/BUILD.gn @@ -120,7 +120,6 @@ if (rtc_include_tests) { deps = [ ":remote_bitrate_estimator", "..:module_api_public", - "../../api/transport:field_trial_based_config", "../../api/transport:mock_network_control", "../../api/transport:network_control", "../../api/units:data_rate", @@ -130,7 +129,7 @@ if (rtc_include_tests) { "../../rtc_base:checks", "../../rtc_base:random", "../../system_wrappers", - "../../test:field_trial", + "../../test:explicit_key_value_config", "../../test:fileutils", "../../test:test_support", "../pacing", diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc index 6c3638b59fd51..b9abb785a5201 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc @@ -35,10 +35,6 @@ constexpr double kDefaultBackoffFactor = 0.85; constexpr char kBweBackOffFactorExperiment[] = "WebRTC-BweBackOffFactor"; -bool IsEnabled(const FieldTrialsView& field_trials, absl::string_view key) { - return absl::StartsWith(field_trials.Lookup(key), "Enabled"); -} - double ReadBackoffFactor(const FieldTrialsView& key_value_config) { std::string experiment_string = key_value_config.Lookup(kBweBackOffFactorExperiment); @@ -61,10 +57,10 @@ double ReadBackoffFactor(const FieldTrialsView& key_value_config) { } // namespace -AimdRateControl::AimdRateControl(const FieldTrialsView* key_value_config) +AimdRateControl::AimdRateControl(const FieldTrialsView& key_value_config) : AimdRateControl(key_value_config, /* send_side =*/false) {} -AimdRateControl::AimdRateControl(const FieldTrialsView* key_value_config, +AimdRateControl::AimdRateControl(const FieldTrialsView& key_value_config, bool send_side) : min_configured_bitrate_(kCongestionControllerMinBitrate), max_configured_bitrate_(DataRate::KilobitsPerSec(30000)), @@ -76,26 +72,23 @@ AimdRateControl::AimdRateControl(const FieldTrialsView* key_value_config, time_last_bitrate_decrease_(Timestamp::MinusInfinity()), time_first_throughput_estimate_(Timestamp::MinusInfinity()), bitrate_is_initialized_(false), - beta_(IsEnabled(*key_value_config, kBweBackOffFactorExperiment) - ? ReadBackoffFactor(*key_value_config) + beta_(key_value_config.IsEnabled(kBweBackOffFactorExperiment) + ? ReadBackoffFactor(key_value_config) : kDefaultBackoffFactor), in_alr_(false), rtt_(kDefaultRtt), send_side_(send_side), no_bitrate_increase_in_alr_( - IsEnabled(*key_value_config, - "WebRTC-DontIncreaseDelayBasedBweInAlr")), + key_value_config.IsEnabled("WebRTC-DontIncreaseDelayBasedBweInAlr")), initial_backoff_interval_("initial_backoff_interval"), link_capacity_fix_("link_capacity_fix") { ParseFieldTrial( - {&disable_estimate_bounded_increase_, &estimate_bounded_increase_ratio_, - &ignore_throughput_limit_if_network_estimate_, - &ignore_network_estimate_decrease_, &increase_to_network_estimate_}, - key_value_config->Lookup("WebRTC-Bwe-EstimateBoundedIncrease")); + {&disable_estimate_bounded_increase_}, + key_value_config.Lookup("WebRTC-Bwe-EstimateBoundedIncrease")); // E.g // WebRTC-BweAimdRateControlConfig/initial_backoff_interval:100ms/ ParseFieldTrial({&initial_backoff_interval_, &link_capacity_fix_}, - key_value_config->Lookup("WebRTC-BweAimdRateControlConfig")); + key_value_config.Lookup("WebRTC-BweAimdRateControlConfig")); if (initial_backoff_interval_) { RTC_LOG(LS_INFO) << "Using aimd rate control with initial back-off interval" " " @@ -171,10 +164,8 @@ void AimdRateControl::SetRtt(TimeDelta rtt) { rtt_ = rtt; } -DataRate AimdRateControl::Update(const RateControlInput* input, +DataRate AimdRateControl::Update(const RateControlInput& input, Timestamp at_time) { - RTC_CHECK(input); - // Set the initial bit rate value to what we're receiving the first half // second. // TODO(bugs.webrtc.org/9379): The comment above doesn't match to the code. @@ -182,17 +173,17 @@ DataRate AimdRateControl::Update(const RateControlInput* input, const TimeDelta kInitializationTime = TimeDelta::Seconds(5); RTC_DCHECK_LE(kBitrateWindowMs, kInitializationTime.ms()); if (time_first_throughput_estimate_.IsInfinite()) { - if (input->estimated_throughput) + if (input.estimated_throughput) time_first_throughput_estimate_ = at_time; } else if (at_time - time_first_throughput_estimate_ > kInitializationTime && - input->estimated_throughput) { - current_bitrate_ = *input->estimated_throughput; + input.estimated_throughput) { + current_bitrate_ = *input.estimated_throughput; bitrate_is_initialized_ = true; } } - ChangeBitrate(*input, at_time); + ChangeBitrate(input, at_time); return current_bitrate_; } @@ -226,7 +217,7 @@ double AimdRateControl::GetNearMaxIncreaseRateBpsPerSecond() const { // Approximate the over-use estimator delay to 100 ms. TimeDelta response_time = rtt_ + TimeDelta::Millis(100); - response_time = response_time * 2; + response_time = response_time * 2; double increase_rate_bps_per_second = (avg_packet_size / response_time).bps(); double kMinIncreaseRateBpsPerSecond = 4000; @@ -277,12 +268,7 @@ void AimdRateControl::ChangeBitrate(const RateControlInput& input, // easily get stuck if the encoder produces uneven outputs. DataRate increase_limit = 1.5 * estimated_throughput + DataRate::KilobitsPerSec(10); - if (ignore_throughput_limit_if_network_estimate_ && network_estimate_ && - network_estimate_->link_capacity_upper.IsFinite()) { - // If we have a Network estimate, we do allow the estimate to increase. - increase_limit = network_estimate_->link_capacity_upper * - estimate_bounded_increase_ratio_.Get(); - } else if (send_side_ && in_alr_ && no_bitrate_increase_in_alr_) { + if (send_side_ && in_alr_ && no_bitrate_increase_in_alr_) { // Do not increase the delay based estimate in alr since the estimator // will not be able to get transport feedback necessary to detect if // the new estimate is correct. @@ -293,10 +279,7 @@ void AimdRateControl::ChangeBitrate(const RateControlInput& input, if (current_bitrate_ < increase_limit) { DataRate increased_bitrate = DataRate::MinusInfinity(); - if (increase_to_network_estimate_ && network_estimate_ && - network_estimate_->link_capacity_upper.IsFinite()) { - increased_bitrate = increase_limit; - } else if (link_capacity_.has_estimate()) { + if (link_capacity_.has_estimate()) { // The link_capacity estimate is reset if the measured throughput // is too far from the estimate. We can therefore assume that our // target rate is reasonably close to link capacity and use additive @@ -367,11 +350,7 @@ void AimdRateControl::ChangeBitrate(const RateControlInput& input, DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate) const { if (!disable_estimate_bounded_increase_ && network_estimate_ && network_estimate_->link_capacity_upper.IsFinite()) { - DataRate upper_bound = network_estimate_->link_capacity_upper * - estimate_bounded_increase_ratio_.Get(); - if (ignore_network_estimate_decrease_) { - upper_bound = std::max(upper_bound, current_bitrate_); - } + DataRate upper_bound = network_estimate_->link_capacity_upper; new_bitrate = std::min(upper_bound, new_bitrate); } if (network_estimate_ && network_estimate_->link_capacity_lower.IsFinite() && diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.h b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.h index 8321fd5239010..91d5a3edb885a 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.h +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control.h @@ -30,8 +30,8 @@ namespace webrtc { // multiplicatively. class AimdRateControl { public: - explicit AimdRateControl(const FieldTrialsView* key_value_config); - AimdRateControl(const FieldTrialsView* key_value_config, bool send_side); + explicit AimdRateControl(const FieldTrialsView& key_value_config); + AimdRateControl(const FieldTrialsView& key_value_config, bool send_side); ~AimdRateControl(); // Returns true if the target bitrate has been initialized. This happens @@ -53,7 +53,7 @@ class AimdRateControl { DataRate LatestEstimate() const; void SetRtt(TimeDelta rtt); - DataRate Update(const RateControlInput* input, Timestamp at_time); + DataRate Update(const RateControlInput& input, Timestamp at_time); void SetInApplicationLimitedRegion(bool in_alr); void SetEstimate(DataRate bitrate, Timestamp at_time); void SetNetworkStateEstimate( @@ -103,16 +103,8 @@ class AimdRateControl { // Allow the delay based estimate to only increase as long as application // limited region (alr) is not detected. const bool no_bitrate_increase_in_alr_; - // If false, uses estimated link capacity upper bound * - // `estimate_bounded_increase_ratio_` as upper limit for the estimate. + // If "Disabled", estimated link capacity is not used as upper bound. FieldTrialFlag disable_estimate_bounded_increase_{"Disabled"}; - FieldTrialParameter estimate_bounded_increase_ratio_{"ratio", 1.0}; - FieldTrialParameter ignore_throughput_limit_if_network_estimate_{ - "ignore_acked", false}; - FieldTrialParameter increase_to_network_estimate_{"immediate_incr", - false}; - FieldTrialParameter ignore_network_estimate_decrease_{"ignore_decr", - false}; absl::optional last_decrease_; FieldTrialOptional initial_backoff_interval_; FieldTrialFlag link_capacity_fix_; diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc index aa80dae55b902..8a5ac849a3967 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc @@ -9,476 +9,272 @@ */ #include "modules/remote_bitrate_estimator/aimd_rate_control.h" -#include - -#include "api/transport/field_trial_based_config.h" #include "api/units/data_rate.h" -#include "system_wrappers/include/clock.h" -#include "test/field_trial.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" namespace webrtc { namespace { -constexpr int64_t kClockInitialTime = 123456; +using ::webrtc::test::ExplicitKeyValueConfig; + +constexpr Timestamp kInitialTime = Timestamp::Millis(123'456); -constexpr int kMinBwePeriodMs = 2000; -constexpr int kDefaultPeriodMs = 3000; -constexpr int kMaxBwePeriodMs = 50000; +constexpr TimeDelta kMinBwePeriod = TimeDelta::Seconds(2); +constexpr TimeDelta kDefaultPeriod = TimeDelta::Seconds(3); +constexpr TimeDelta kMaxBwePeriod = TimeDelta::Seconds(50); // After an overuse, we back off to 85% to the received bitrate. constexpr double kFractionAfterOveruse = 0.85; -struct AimdRateControlStates { - std::unique_ptr aimd_rate_control; - std::unique_ptr simulated_clock; - FieldTrialBasedConfig field_trials; -}; - -AimdRateControlStates CreateAimdRateControlStates(bool send_side = false) { - AimdRateControlStates states; - states.aimd_rate_control.reset( - new AimdRateControl(&states.field_trials, send_side)); - states.simulated_clock.reset(new SimulatedClock(kClockInitialTime)); - return states; -} -absl::optional OptionalRateFromOptionalBps( - absl::optional bitrate_bps) { - if (bitrate_bps) { - return DataRate::BitsPerSec(*bitrate_bps); - } else { - return absl::nullopt; - } -} -void UpdateRateControl(const AimdRateControlStates& states, - const BandwidthUsage& bandwidth_usage, - absl::optional throughput_estimate, - int64_t now_ms) { - RateControlInput input(bandwidth_usage, - OptionalRateFromOptionalBps(throughput_estimate)); - states.aimd_rate_control->Update(&input, Timestamp::Millis(now_ms)); -} -void SetEstimate(const AimdRateControlStates& states, int bitrate_bps) { - states.aimd_rate_control->SetEstimate(DataRate::BitsPerSec(bitrate_bps), - states.simulated_clock->CurrentTime()); -} - } // namespace TEST(AimdRateControlTest, MinNearMaxIncreaseRateOnLowBandwith) { - auto states = CreateAimdRateControlStates(); - constexpr int kBitrate = 30000; - SetEstimate(states, kBitrate); - EXPECT_EQ(4000, - states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + aimd_rate_control.SetEstimate(DataRate::BitsPerSec(30'000), kInitialTime); + EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 4'000); } TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn90kbpsAnd200msRtt) { - auto states = CreateAimdRateControlStates(); - constexpr int kBitrate = 90000; - SetEstimate(states, kBitrate); - EXPECT_EQ(5000, - states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + aimd_rate_control.SetEstimate(DataRate::BitsPerSec(90'000), kInitialTime); + EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 5'000); } TEST(AimdRateControlTest, NearMaxIncreaseRateIs5kbpsOn60kbpsAnd100msRtt) { - auto states = CreateAimdRateControlStates(); - constexpr int kBitrate = 60000; - SetEstimate(states, kBitrate); - states.aimd_rate_control->SetRtt(TimeDelta::Millis(100)); - EXPECT_EQ(5000, - states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + aimd_rate_control.SetEstimate(DataRate::BitsPerSec(60'000), kInitialTime); + aimd_rate_control.SetRtt(TimeDelta::Millis(100)); + EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 5'000); } TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) { - // Smoothing experiment disabled - auto states = CreateAimdRateControlStates(); - constexpr int kBitrate = 300000; - SetEstimate(states, kBitrate); - UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_NEAR(14000, - states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond(), - 1000); - EXPECT_EQ(kDefaultPeriodMs, - states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kBitrate = DataRate::BitsPerSec(300'000); + aimd_rate_control.SetEstimate(kBitrate, kInitialTime); + aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kBitrate}, + kInitialTime); + EXPECT_NEAR(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 14'000, + 1'000); + EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod); } TEST(AimdRateControlTest, BweLimitedByAckedBitrate) { - auto states = CreateAimdRateControlStates(); - constexpr int kAckedBitrate = 10000; - SetEstimate(states, kAckedBitrate); - while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime < - 20000) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kAckedBitrate = DataRate::BitsPerSec(10'000); + Timestamp now = kInitialTime; + aimd_rate_control.SetEstimate(kAckedBitrate, now); + while (now - kInitialTime < TimeDelta::Seconds(20)) { + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate}, now); + now += TimeDelta::Millis(100); } - ASSERT_TRUE(states.aimd_rate_control->ValidEstimate()); - EXPECT_EQ(static_cast(1.5 * kAckedBitrate + 10000), - states.aimd_rate_control->LatestEstimate().bps()); + ASSERT_TRUE(aimd_rate_control.ValidEstimate()); + EXPECT_EQ(aimd_rate_control.LatestEstimate(), + 1.5 * kAckedBitrate + DataRate::BitsPerSec(10'000)); } TEST(AimdRateControlTest, BweNotLimitedByDecreasingAckedBitrate) { - auto states = CreateAimdRateControlStates(); - constexpr int kAckedBitrate = 100000; - SetEstimate(states, kAckedBitrate); - while (states.simulated_clock->TimeInMilliseconds() - kClockInitialTime < - 20000) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kAckedBitrate = DataRate::BitsPerSec(10'000); + Timestamp now = kInitialTime; + aimd_rate_control.SetEstimate(kAckedBitrate, now); + while (now - kInitialTime < TimeDelta::Seconds(20)) { + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate}, now); + now += TimeDelta::Millis(100); } - ASSERT_TRUE(states.aimd_rate_control->ValidEstimate()); + ASSERT_TRUE(aimd_rate_control.ValidEstimate()); // If the acked bitrate decreases the BWE shouldn't be reduced to 1.5x // what's being acked, but also shouldn't get to increase more. - uint32_t prev_estimate = states.aimd_rate_control->LatestEstimate().bps(); - UpdateRateControl(states, BandwidthUsage::kBwNormal, kAckedBitrate / 2, - states.simulated_clock->TimeInMilliseconds()); - uint32_t new_estimate = states.aimd_rate_control->LatestEstimate().bps(); - EXPECT_NEAR(new_estimate, static_cast(1.5 * kAckedBitrate + 10000), - 2000); + DataRate prev_estimate = aimd_rate_control.LatestEstimate(); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kAckedBitrate / 2}, now); + DataRate new_estimate = aimd_rate_control.LatestEstimate(); EXPECT_EQ(new_estimate, prev_estimate); + EXPECT_NEAR(new_estimate.bps(), + (1.5 * kAckedBitrate + DataRate::BitsPerSec(10'000)).bps(), + 2'000); } TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) { - // Smoothing experiment disabled - auto states = CreateAimdRateControlStates(); - states.aimd_rate_control->SetStartBitrate(DataRate::KilobitsPerSec(300)); - EXPECT_EQ(kDefaultPeriodMs, - states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_NE(kDefaultPeriodMs, - states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + aimd_rate_control.SetStartBitrate(DataRate::KilobitsPerSec(300)); + EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod); + aimd_rate_control.Update( + {BandwidthUsage::kBwOverusing, DataRate::KilobitsPerSec(280)}, + kInitialTime); + EXPECT_NE(aimd_rate_control.GetExpectedBandwidthPeriod(), kDefaultPeriod); } TEST(AimdRateControlTest, ExpectedPeriodAfter20kbpsDropAnd5kbpsIncrease) { - auto states = CreateAimdRateControlStates(); - constexpr int kInitialBitrate = 110000; - SetEstimate(states, kInitialBitrate); - states.simulated_clock->AdvanceTimeMilliseconds(100); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(110'000); + Timestamp now = kInitialTime; + aimd_rate_control.SetEstimate(kInitialBitrate, now); + now += TimeDelta::Millis(100); // Make the bitrate drop by 20 kbps to get to 90 kbps. // The rate increase at 90 kbps should be 5 kbps, so the period should be 4 s. - constexpr int kAckedBitrate = - (kInitialBitrate - 20000) / kFractionAfterOveruse; - UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_EQ(5000, - states.aimd_rate_control->GetNearMaxIncreaseRateBpsPerSecond()); - EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); + const DataRate kAckedBitrate = + (kInitialBitrate - DataRate::BitsPerSec(20'000)) / kFractionAfterOveruse; + aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kAckedBitrate}, now); + EXPECT_EQ(aimd_rate_control.GetNearMaxIncreaseRateBpsPerSecond(), 5'000); + EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), + TimeDelta::Seconds(4)); } TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) { - auto states = CreateAimdRateControlStates(); - constexpr int kInitialBitrate = 10000; - SetEstimate(states, kInitialBitrate); - states.simulated_clock->AdvanceTimeMilliseconds(100); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(10'000); + Timestamp now = kInitialTime; + aimd_rate_control.SetEstimate(kInitialBitrate, now); + now += TimeDelta::Millis(100); // Make a small (1.5 kbps) bitrate drop to 8.5 kbps. - UpdateRateControl(states, BandwidthUsage::kBwOverusing, kInitialBitrate - 1, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_EQ(kMinBwePeriodMs, - states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); + aimd_rate_control.Update( + {BandwidthUsage::kBwOverusing, kInitialBitrate - DataRate::BitsPerSec(1)}, + now); + EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kMinBwePeriod); } TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxNoSmoothingExp) { - auto states = CreateAimdRateControlStates(); - constexpr int kInitialBitrate = 10010000; - SetEstimate(states, kInitialBitrate); - states.simulated_clock->AdvanceTimeMilliseconds(100); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(10'010'000); + Timestamp now = kInitialTime; + aimd_rate_control.SetEstimate(kInitialBitrate, now); + now += TimeDelta::Millis(100); // Make a large (10 Mbps) bitrate drop to 10 kbps. - constexpr int kAckedBitrate = 10000 / kFractionAfterOveruse; - UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_EQ(kMaxBwePeriodMs, - states.aimd_rate_control->GetExpectedBandwidthPeriod().ms()); + const DataRate kAckedBitrate = + DataRate::BitsPerSec(10'000) / kFractionAfterOveruse; + aimd_rate_control.Update({BandwidthUsage::kBwOverusing, kAckedBitrate}, now); + EXPECT_EQ(aimd_rate_control.GetExpectedBandwidthPeriod(), kMaxBwePeriod); } TEST(AimdRateControlTest, SendingRateBoundedWhenThroughputNotEstimated) { - auto states = CreateAimdRateControlStates(); - constexpr int kInitialBitrateBps = 123000; - UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps, - states.simulated_clock->TimeInMilliseconds()); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig("")); + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000); + Timestamp now = kInitialTime; + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now); // AimdRateControl sets the initial bit rate to what it receives after // five seconds has passed. // TODO(bugs.webrtc.org/9379): The comment in the AimdRateControl does not // match the constant. - constexpr int kInitializationTimeMs = 5000; - states.simulated_clock->AdvanceTimeMilliseconds(kInitializationTimeMs + 1); - UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps, - states.simulated_clock->TimeInMilliseconds()); + constexpr TimeDelta kInitializationTime = TimeDelta::Seconds(5); + now += (kInitializationTime + TimeDelta::Millis(1)); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now); for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now); + now += TimeDelta::Millis(100); } - EXPECT_LE(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps * 1.5 + 10000); + EXPECT_LE(aimd_rate_control.LatestEstimate(), + kInitialBitrate * 1.5 + DataRate::BitsPerSec(10'000)); } TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlr) { // When alr is detected, the delay based estimator is not allowed to increase // bwe since there will be no feedback from the network if the new estimate // is correct. - test::ScopedFieldTrials override_field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(true); - UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps, - states.simulated_clock->TimeInMilliseconds()); - ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); + AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true); + Timestamp now = kInitialTime; + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000); + aimd_rate_control.SetEstimate(kInitialBitrate, now); + aimd_rate_control.SetInApplicationLimitedRegion(true); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now); + ASSERT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate); for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now); + now += TimeDelta::Millis(100); } - EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); + EXPECT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate); } TEST(AimdRateControlTest, SetEstimateIncreaseBweInAlr) { - test::ScopedFieldTrials override_field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(true); - ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); - SetEstimate(states, 2 * kInitialBitrateBps); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - 2 * kInitialBitrateBps); + AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true); + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000); + aimd_rate_control.SetEstimate(kInitialBitrate, kInitialTime); + aimd_rate_control.SetInApplicationLimitedRegion(true); + ASSERT_EQ(aimd_rate_control.LatestEstimate(), kInitialBitrate); + aimd_rate_control.SetEstimate(2 * kInitialBitrate, kInitialTime); + EXPECT_EQ(aimd_rate_control.LatestEstimate(), 2 * kInitialBitrate); } TEST(AimdRateControlTest, SetEstimateUpperLimitedByNetworkEstimate) { - auto states = CreateAimdRateControlStates(/*send_side=*/true); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""), + /*send_side=*/true); NetworkStateEstimate network_estimate; - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - SetEstimate(states, 500'000); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), + network_estimate.link_capacity_upper = DataRate::BitsPerSec(400'000); + aimd_rate_control.SetNetworkStateEstimate(network_estimate); + aimd_rate_control.SetEstimate(DataRate::BitsPerSec(500'000), kInitialTime); + EXPECT_EQ(aimd_rate_control.LatestEstimate(), network_estimate.link_capacity_upper); } TEST(AimdRateControlTest, SetEstimateLowerLimitedByNetworkEstimate) { - auto states = CreateAimdRateControlStates(/*send_side=*/true); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""), + /*send_side=*/true); NetworkStateEstimate network_estimate; - network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(400); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - SetEstimate(states, 100'000); + network_estimate.link_capacity_lower = DataRate::BitsPerSec(400'000); + aimd_rate_control.SetNetworkStateEstimate(network_estimate); + aimd_rate_control.SetEstimate(DataRate::BitsPerSec(100'000), kInitialTime); // 0.85 is default backoff factor. (`beta_`) - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), + EXPECT_EQ(aimd_rate_control.LatestEstimate(), network_estimate.link_capacity_lower * 0.85); } TEST(AimdRateControlTest, SetEstimateIgnoredIfLowerThanNetworkEstimateAndCurrent) { - auto states = CreateAimdRateControlStates(/*send_side=*/true); - SetEstimate(states, 200'000); - ASSERT_EQ(states.aimd_rate_control->LatestEstimate().kbps(), 200); + AimdRateControl aimd_rate_control(ExplicitKeyValueConfig(""), + /*send_side=*/true); + aimd_rate_control.SetEstimate(DataRate::KilobitsPerSec(200), kInitialTime); + ASSERT_EQ(aimd_rate_control.LatestEstimate().kbps(), 200); NetworkStateEstimate network_estimate; network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(400); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); + aimd_rate_control.SetNetworkStateEstimate(network_estimate); // Ignore the next SetEstimate, since the estimate is lower than 85% of // the network estimate. - SetEstimate(states, 100'000); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate().kbps(), 200); -} - -TEST(AimdRateControlTest, SetEstimateIgnoresNetworkEstimatesLowerThanCurrent) { - test::ScopedFieldTrials override_field_trials( - "WebRTC-Bwe-EstimateBoundedIncrease/" - "ratio:0.85,ignore_acked:true,ignore_decr:true/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - states.aimd_rate_control->SetStartBitrate(DataRate::KilobitsPerSec(30)); - NetworkStateEstimate network_estimate; - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - SetEstimate(states, 500'000); - ASSERT_EQ(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_upper * 0.85); - - NetworkStateEstimate lower_network_estimate; - lower_network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(300); - states.aimd_rate_control->SetNetworkStateEstimate(lower_network_estimate); - SetEstimate(states, 500'000); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_upper * 0.85); + aimd_rate_control.SetEstimate(DataRate::KilobitsPerSec(100), kInitialTime); + EXPECT_EQ(aimd_rate_control.LatestEstimate().kbps(), 200); } TEST(AimdRateControlTest, EstimateIncreaseWhileNotInAlr) { // Allow the estimate to increase as long as alr is not detected to ensure // tha BWE can not get stuck at a certain bitrate. - test::ScopedFieldTrials override_field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(false); - UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps, - states.simulated_clock->TimeInMilliseconds()); + AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true); + Timestamp now = kInitialTime; + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000); + aimd_rate_control.SetEstimate(kInitialBitrate, now); + aimd_rate_control.SetInApplicationLimitedRegion(false); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, kInitialBitrate}, now); for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now); + now += TimeDelta::Millis(100); } - EXPECT_GT(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); + EXPECT_GT(aimd_rate_control.LatestEstimate(), kInitialBitrate); } TEST(AimdRateControlTest, EstimateNotLimitedByNetworkEstimateIfDisabled) { - test::ScopedFieldTrials override_field_trials( + ExplicitKeyValueConfig field_trials( "WebRTC-Bwe-EstimateBoundedIncrease/Disabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(false); + AimdRateControl aimd_rate_control(field_trials, /*send_side=*/true); + Timestamp now = kInitialTime; + constexpr DataRate kInitialBitrate = DataRate::BitsPerSec(123'000); + aimd_rate_control.SetEstimate(kInitialBitrate, now); + aimd_rate_control.SetInApplicationLimitedRegion(false); NetworkStateEstimate network_estimate; network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(150); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); + aimd_rate_control.SetNetworkStateEstimate(network_estimate); for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); + aimd_rate_control.Update({BandwidthUsage::kBwNormal, absl::nullopt}, now); + now += TimeDelta::Millis(100); } - EXPECT_GT(states.aimd_rate_control->LatestEstimate(), + EXPECT_GT(aimd_rate_control.LatestEstimate(), network_estimate.link_capacity_upper); } -TEST(AimdRateControlTest, - EstimateSlowlyIncreaseToUpperLinkCapacityEstimateIfConfigured) { - // Even if alr is detected, the delay based estimator is allowed to increase - // up to a percentage of upper link capacity. - test::ScopedFieldTrials override_field_trials( - "WebRTC-Bwe-EstimateBoundedIncrease/" - "ratio:0.85,ignore_acked:true,immediate_incr:false/" - "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(true); - - NetworkStateEstimate network_estimate; - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - for (int i = 0; i < 10; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - EXPECT_LT(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_upper * 0.85); - } - for (int i = 0; i < 50; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - } - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_upper * 0.85); -} - -TEST(AimdRateControlTest, - EstimateImmediatelyIncreaseToUpperLinkCapacityEstimateIfConfigured) { - // Even if alr is detected, the delay based estimator is allowed to increase - // up to a percentage of upper link capacity. - test::ScopedFieldTrials override_field_trials( - "WebRTC-Bwe-EstimateBoundedIncrease/" - "ratio:0.85,ignore_acked:true,immediate_incr:true/" - "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(true); - - NetworkStateEstimate network_estimate; - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_upper * 0.85); -} - -TEST(AimdRateControlTest, EstimateNotLoweredByNetworkEstimate) { - // The delay based estimator is allowed to increase up to a percentage of - // upper link capacity but does not decrease unless the delay detector - // discover an overuse. - test::ScopedFieldTrials override_field_trials( - "WebRTC-Bwe-EstimateBoundedIncrease/" - "ratio:0.85,ignore_acked:true,ignore_decr:true/" - "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - constexpr int kEstimatedThroughputBps = 30'000; - SetEstimate(states, kInitialBitrateBps); - - NetworkStateEstimate network_estimate; - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, - kEstimatedThroughputBps, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - } - DataRate estimate_after_increase = states.aimd_rate_control->LatestEstimate(); - ASSERT_EQ(estimate_after_increase, - network_estimate.link_capacity_upper * 0.85); - - // A lower network estimate does not decrease the estimate immediately, - // but the estimate is not allowed to increase. - network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(100); - network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(80); - states.aimd_rate_control->SetNetworkStateEstimate(network_estimate); - for (int i = 0; i < 10; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, - kEstimatedThroughputBps, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - EXPECT_EQ(states.aimd_rate_control->LatestEstimate(), - estimate_after_increase); - } - - // If the detector detects and overuse, BWE drops to a value relative the - // network estimate. - UpdateRateControl(states, BandwidthUsage::kBwOverusing, - kEstimatedThroughputBps, - states.simulated_clock->TimeInMilliseconds()); - EXPECT_LT(states.aimd_rate_control->LatestEstimate(), - network_estimate.link_capacity_lower); - EXPECT_GT(states.aimd_rate_control->LatestEstimate().bps(), - kEstimatedThroughputBps); -} - -TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlrIfNetworkEstimateNotSet) { - // When alr is detected, the delay based estimator is not allowed to increase - // bwe since there will be no feedback from the network if the new estimate - // is correct. - test::ScopedFieldTrials override_field_trials( - "WebRTC-Bwe-EstimateBoundedIncrease/ratio:0.85,ignore_acked:true/" - "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/"); - auto states = CreateAimdRateControlStates(/*send_side=*/true); - constexpr int kInitialBitrateBps = 123000; - SetEstimate(states, kInitialBitrateBps); - states.aimd_rate_control->SetInApplicationLimitedRegion(true); - UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps, - states.simulated_clock->TimeInMilliseconds()); - ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); - - for (int i = 0; i < 100; ++i) { - UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt, - states.simulated_clock->TimeInMilliseconds()); - states.simulated_clock->AdvanceTimeMilliseconds(100); - } - EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(), - kInitialBitrateBps); -} - } // namespace webrtc diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.cc index bd2d7568768fa..888f18cd9ea5a 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.cc @@ -21,25 +21,17 @@ #include "rtc_base/numerics/safe_minmax.h" namespace webrtc { +namespace { -const double kMaxAdaptOffsetMs = 15.0; -const double kOverUsingTimeThreshold = 10; -const int kMaxNumDeltas = 60; - -OveruseDetector::OveruseDetector(const FieldTrialsView* key_value_config) - // Experiment is on by default, but can be disabled with finch by setting - // the field trial string to "WebRTC-AdaptiveBweThreshold/Disabled/". - : k_up_(0.0087), - k_down_(0.039), - overusing_time_threshold_(kOverUsingTimeThreshold), - threshold_(12.5), - last_update_ms_(-1), - prev_offset_(0.0), - time_over_using_(-1), - overuse_counter_(0), - hypothesis_(BandwidthUsage::kBwNormal) {} - -OveruseDetector::~OveruseDetector() {} +constexpr double kMaxAdaptOffsetMs = 15.0; +constexpr double kOverUsingTimeThreshold = 10; +constexpr int kMaxNumDeltas = 60; +constexpr double kUp = 0.0087; +constexpr double kDown = 0.039; + +} // namespace + +OveruseDetector::OveruseDetector() = default; BandwidthUsage OveruseDetector::State() const { return hypothesis_; @@ -66,7 +58,7 @@ BandwidthUsage OveruseDetector::Detect(double offset, time_over_using_ += ts_delta; } overuse_counter_++; - if (time_over_using_ > overusing_time_threshold_ && overuse_counter_ > 1) { + if (time_over_using_ > kOverUsingTimeThreshold && overuse_counter_ > 1) { if (offset >= prev_offset_) { time_over_using_ = 0; overuse_counter_ = 0; @@ -100,7 +92,7 @@ void OveruseDetector::UpdateThreshold(double modified_offset, int64_t now_ms) { return; } - const double k = fabs(modified_offset) < threshold_ ? k_down_ : k_up_; + const double k = fabs(modified_offset) < threshold_ ? kDown : kUp; const int64_t kMaxTimeDeltaMs = 100; int64_t time_delta_ms = std::min(now_ms - last_update_ms_, kMaxTimeDeltaMs); threshold_ += k * (fabs(modified_offset) - threshold_) * time_delta_ms; diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.h b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.h index 07ae8734c4853..444e8eece5c26 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.h +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector.h @@ -12,19 +12,19 @@ #include -#include "api/field_trials_view.h" #include "api/network_state_predictor.h" namespace webrtc { class OveruseDetector { public: - explicit OveruseDetector(const FieldTrialsView* key_value_config); - virtual ~OveruseDetector(); + OveruseDetector(); OveruseDetector(const OveruseDetector&) = delete; OveruseDetector& operator=(const OveruseDetector&) = delete; + ~OveruseDetector() = default; + // Update the detection state based on the estimated inter-arrival time delta // offset. `timestamp_delta` is the delta between the last timestamp which the // estimated offset is based on and the last timestamp on which the last @@ -41,17 +41,13 @@ class OveruseDetector { private: void UpdateThreshold(double modified_offset, int64_t now_ms); - void InitializeExperiment(const FieldTrialsView& key_value_config); - - const double k_up_; - const double k_down_; - const double overusing_time_threshold_; - double threshold_; - int64_t last_update_ms_; - double prev_offset_; - double time_over_using_; - int overuse_counter_; - BandwidthUsage hypothesis_; + + double threshold_ = 12.5; + int64_t last_update_ms_ = -1; + double prev_offset_ = 0.0; + double time_over_using_ = -1; + int overuse_counter_ = 0; + BandwidthUsage hypothesis_ = BandwidthUsage::kBwNormal; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc index 82786521d7337..c4c72b1de5225 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/overuse_detector_unittest.cc @@ -17,7 +17,6 @@ #include #include -#include "api/transport/field_trial_based_config.h" #include "modules/remote_bitrate_estimator/inter_arrival.h" #include "modules/remote_bitrate_estimator/overuse_estimator.h" #include "rtc_base/random.h" @@ -34,15 +33,10 @@ class OveruseDetectorTest : public ::testing::Test { : now_ms_(0), receive_time_ms_(0), rtp_timestamp_(10 * 90), - overuse_detector_(), inter_arrival_(5 * 90, kRtpTimestampToMs), random_(123456789) {} protected: - void SetUp() override { - overuse_detector_.reset(new OveruseDetector(&field_trials_)); - } - int Run100000Samples(int packets_per_frame, size_t packet_size, int mean_ms, @@ -59,7 +53,7 @@ class OveruseDetectorTest : public ::testing::Test { receive_time_ms_, now_ms_ + static_cast( random_.Gaussian(0, standard_deviation_ms) + 0.5)); - if (BandwidthUsage::kBwOverusing == overuse_detector_->State()) { + if (BandwidthUsage::kBwOverusing == overuse_detector_.State()) { if (last_overuse + 1 != i) { unique_overuse++; } @@ -85,7 +79,7 @@ class OveruseDetectorTest : public ::testing::Test { receive_time_ms_, now_ms_ + static_cast( random_.Gaussian(0, standard_deviation_ms) + 0.5)); - if (BandwidthUsage::kBwOverusing == overuse_detector_->State()) { + if (BandwidthUsage::kBwOverusing == overuse_detector_.State()) { return i + 1; } } @@ -103,18 +97,17 @@ class OveruseDetectorTest : public ::testing::Test { ×tamp_delta, &time_delta, &size_delta)) { double timestamp_delta_ms = timestamp_delta / 90.0; overuse_estimator_.Update(time_delta, timestamp_delta_ms, size_delta, - overuse_detector_->State(), receive_time_ms); - overuse_detector_->Detect(overuse_estimator_.offset(), timestamp_delta_ms, - overuse_estimator_.num_of_deltas(), - receive_time_ms); + overuse_detector_.State(), receive_time_ms); + overuse_detector_.Detect(overuse_estimator_.offset(), timestamp_delta_ms, + overuse_estimator_.num_of_deltas(), + receive_time_ms); } } - const FieldTrialBasedConfig field_trials_; int64_t now_ms_; int64_t receive_time_ms_; uint32_t rtp_timestamp_; - std::unique_ptr overuse_detector_; + OveruseDetector overuse_detector_; OveruseEstimator overuse_estimator_; InterArrival inter_arrival_; Random random_; @@ -143,7 +136,7 @@ TEST_F(OveruseDetectorTest, SimpleNonOveruse30fps) { UpdateDetector(rtp_timestamp, now_ms_, packet_size); now_ms_ += frame_duration_ms; rtp_timestamp += frame_duration_ms * 90; - EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_.State()); } } @@ -161,7 +154,7 @@ TEST_F(OveruseDetectorTest, SimpleNonOveruseWithReceiveVariance) { } else { now_ms_ += frame_duration_ms + 5; } - EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_.State()); } } @@ -179,7 +172,7 @@ TEST_F(OveruseDetectorTest, SimpleNonOveruseWithRtpTimestampVariance) { } else { rtp_timestamp += (frame_duration_ms + 5) * 90; } - EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_.State()); } } @@ -237,7 +230,7 @@ TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) { } else { now_ms_ += frame_duration_ms + offset; } - EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_.State()); } // Simulate a higher send pace, that is too high. // Total build up of 30 ms. @@ -250,10 +243,10 @@ TEST_F(OveruseDetectorTest, OveruseWithLowVariance2000Kbit30fps) { UpdateDetector(rtp_timestamp, now_ms_, packet_size); now_ms_ += frame_duration_ms + drift_per_frame_ms * 6; rtp_timestamp += frame_duration_ms * 90; - EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwNormal, overuse_detector_.State()); } UpdateDetector(rtp_timestamp, now_ms_, packet_size); - EXPECT_EQ(BandwidthUsage::kBwOverusing, overuse_detector_->State()); + EXPECT_EQ(BandwidthUsage::kBwOverusing, overuse_detector_.State()); } TEST_F(OveruseDetectorTest, LowGaussianVariance30Kbit3fps) { @@ -567,7 +560,7 @@ TEST_F(OveruseDetectorTest, ThresholdAdapts) { bool overuse_detected = false; for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -580,7 +573,7 @@ TEST_F(OveruseDetectorTest, ThresholdAdapts) { overuse_detected = false; for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(1.1 * kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(1.1 * kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -593,7 +586,7 @@ TEST_F(OveruseDetectorTest, ThresholdAdapts) { overuse_detected = false; for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -605,7 +598,7 @@ TEST_F(OveruseDetectorTest, ThresholdAdapts) { // Pass in a low offset to make the threshold adapt down. for (int i = 0; i < 15 * kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(0.7 * kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(0.7 * kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -617,7 +610,7 @@ TEST_F(OveruseDetectorTest, ThresholdAdapts) { // Make sure the original offset now again triggers overuse. for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -640,7 +633,7 @@ TEST_F(OveruseDetectorTest, DoesntAdaptToSpikes) { bool overuse_detected = false; for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -654,7 +647,7 @@ TEST_F(OveruseDetectorTest, DoesntAdaptToSpikes) { overuse_detected = false; for (int i = 0; i < kShortBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kLargeOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kLargeOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } @@ -667,7 +660,7 @@ TEST_F(OveruseDetectorTest, DoesntAdaptToSpikes) { overuse_detected = false; for (int i = 0; i < kBatchLength; ++i) { BandwidthUsage overuse_state = - overuse_detector_->Detect(kOffset, kTsDelta, num_deltas, now_ms); + overuse_detector_.Detect(kOffset, kTsDelta, num_deltas, now_ms); if (overuse_state == BandwidthUsage::kBwOverusing) { overuse_detected = true; } diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc index a07348c766370..135f5f34246de 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc @@ -97,10 +97,7 @@ void RemoteBitrateEstimatorAbsSendTime::MaybeAddCluster( RemoteBitrateEstimatorAbsSendTime::RemoteBitrateEstimatorAbsSendTime( RemoteBitrateObserver* observer, Clock* clock) - : clock_(clock), - observer_(observer), - detector_(&field_trials_), - remote_rate_(&field_trials_) { + : clock_(clock), observer_(observer), remote_rate_(field_trials_) { RTC_DCHECK(clock_); RTC_DCHECK(observer_); RTC_LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating."; @@ -336,7 +333,7 @@ void RemoteBitrateEstimatorAbsSendTime::IncomingPacketInfo( const RateControlInput input( detector_.State(), OptionalRateFromOptionalBps(incoming_bitrate_.Rate(arrival_time.ms()))); - target_bitrate = remote_rate_.Update(&input, now); + target_bitrate = remote_rate_.Update(input, now); update_estimate = remote_rate_.ValidEstimate(); } diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index bc06d4e4b585c..20326286fa302 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -10,7 +10,6 @@ #include "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" - #include #include @@ -41,11 +40,9 @@ enum { kTimestampGroupLengthMs = 5 }; static const double kTimestampToMs = 1.0 / 90.0; struct RemoteBitrateEstimatorSingleStream::Detector { - explicit Detector(int64_t last_packet_time_ms, - const FieldTrialsView* key_value_config) + explicit Detector(int64_t last_packet_time_ms) : last_packet_time_ms(last_packet_time_ms), - inter_arrival(90 * kTimestampGroupLengthMs, kTimestampToMs), - detector(key_value_config) {} + inter_arrival(90 * kTimestampGroupLengthMs, kTimestampToMs) {} int64_t last_packet_time_ms; InterArrival inter_arrival; @@ -59,7 +56,7 @@ RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream( : clock_(clock), incoming_bitrate_(kBitrateWindowMs, 8000), last_valid_incoming_bitrate_(0), - remote_rate_(&field_trials_), + remote_rate_(field_trials_), observer_(observer), last_process_time_(-1), process_interval_ms_(kProcessIntervalMs), @@ -99,8 +96,7 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket( // automatically cleaned up when we have one RemoteBitrateEstimator per REMB // group. std::pair insert_result = - overuse_detectors_.insert( - std::make_pair(ssrc, new Detector(now_ms, &field_trials_))); + overuse_detectors_.insert(std::make_pair(ssrc, new Detector(now_ms))); it = insert_result.first; } Detector* estimator = it->second; @@ -190,7 +186,7 @@ void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) { const RateControlInput input( bw_state, OptionalRateFromOptionalBps(incoming_bitrate_.Rate(now_ms))); uint32_t target_bitrate = - remote_rate_.Update(&input, Timestamp::Millis(now_ms)).bps(); + remote_rate_.Update(input, Timestamp::Millis(now_ms)).bps(); if (remote_rate_.ValidEstimate()) { process_interval_ms_ = remote_rate_.GetFeedbackInterval().ms(); RTC_DCHECK_GT(process_interval_ms_, 0); diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc index 01a23ba9b035a..c417f35fb6b66 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.cc @@ -28,9 +28,7 @@ namespace webrtc { namespace { -// The maximum allowed value for a timestamp in milliseconds. This is lower -// than the numerical limit since we often convert to microseconds. -constexpr int64_t kMaxTimeMs = std::numeric_limits::max() / 1000; + constexpr TimeDelta kBackWindow = TimeDelta::Millis(500); constexpr TimeDelta kMinInterval = TimeDelta::Millis(50); constexpr TimeDelta kMaxInterval = TimeDelta::Millis(250); @@ -89,15 +87,11 @@ void RemoteEstimatorProxy::IncomingPacket(const RtpPacketReceived& packet) { return; } - Packet internal_packet = {.arrival_time = packet.arrival_time(), - .size = DataSize::Bytes(packet.size()), - .ssrc = packet.Ssrc()}; - uint16_t seqnum; - if (packet.GetExtension(&seqnum) || - packet.GetExtension( - &seqnum, &internal_packet.feedback_request)) { - internal_packet.transport_sequence_number = seqnum; - } else { + uint16_t seqnum = 0; + absl::optional feedback_request; + if (!packet.GetExtension(&seqnum) && + !packet.GetExtension(&seqnum, + &feedback_request)) { // This function expected to be called only for packets that have // TransportSequenceNumber rtp header extension, however malformed RTP // packet may contain unparsable TransportSequenceNumber. @@ -107,81 +101,49 @@ void RemoteEstimatorProxy::IncomingPacket(const RtpPacketReceived& packet) { return; } - internal_packet.absolute_send_time_24bits = - packet.GetExtension(); - MutexLock lock(&lock_); send_periodic_feedback_ = packet.HasExtension(); - IncomingPacket(internal_packet); -} - -void RemoteEstimatorProxy::IncomingPacket(int64_t arrival_time_ms, - size_t payload_size, - const RTPHeader& header) { - if (arrival_time_ms < 0 || arrival_time_ms >= kMaxTimeMs) { - RTC_LOG(LS_WARNING) << "Arrival time out of bounds: " << arrival_time_ms; - return; - } - Packet packet = {.arrival_time = Timestamp::Millis(arrival_time_ms), - .size = DataSize::Bytes(header.headerLength + payload_size), - .ssrc = header.ssrc}; - if (header.extension.hasTransportSequenceNumber) { - packet.transport_sequence_number = header.extension.transportSequenceNumber; - } - if (header.extension.hasAbsoluteSendTime) { - packet.absolute_send_time_24bits = header.extension.absoluteSendTime; - } - packet.feedback_request = header.extension.feedback_request; - - MutexLock lock(&lock_); - IncomingPacket(packet); -} - -void RemoteEstimatorProxy::IncomingPacket(Packet packet) { - media_ssrc_ = packet.ssrc; - int64_t seq = 0; - - if (packet.transport_sequence_number.has_value()) { - seq = unwrapper_.Unwrap(*packet.transport_sequence_number); + media_ssrc_ = packet.Ssrc(); + int64_t seq = unwrapper_.Unwrap(seqnum); - if (send_periodic_feedback_) { - MaybeCullOldPackets(seq, packet.arrival_time); + if (send_periodic_feedback_) { + MaybeCullOldPackets(seq, packet.arrival_time()); - if (!periodic_window_start_seq_ || seq < *periodic_window_start_seq_) { - periodic_window_start_seq_ = seq; - } + if (!periodic_window_start_seq_ || seq < *periodic_window_start_seq_) { + periodic_window_start_seq_ = seq; } + } - // We are only interested in the first time a packet is received. - if (packet_arrival_times_.has_received(seq)) { - return; - } + // We are only interested in the first time a packet is received. + if (packet_arrival_times_.has_received(seq)) { + return; + } - packet_arrival_times_.AddPacket(seq, packet.arrival_time); + packet_arrival_times_.AddPacket(seq, packet.arrival_time()); - // Limit the range of sequence numbers to send feedback for. - if (!periodic_window_start_seq_.has_value() || - periodic_window_start_seq_.value() < - packet_arrival_times_.begin_sequence_number()) { - periodic_window_start_seq_ = - packet_arrival_times_.begin_sequence_number(); - } + // Limit the range of sequence numbers to send feedback for. + if (periodic_window_start_seq_ < + packet_arrival_times_.begin_sequence_number()) { + periodic_window_start_seq_ = packet_arrival_times_.begin_sequence_number(); + } - if (packet.feedback_request) { - // Send feedback packet immediately. - SendFeedbackOnRequest(seq, *packet.feedback_request); - } + if (feedback_request.has_value()) { + // Send feedback packet immediately. + SendFeedbackOnRequest(seq, *feedback_request); } - if (network_state_estimator_ && packet.absolute_send_time_24bits) { + absl::optional absolute_send_time_24bits = + packet.GetExtension(); + if (network_state_estimator_ && absolute_send_time_24bits.has_value()) { PacketResult packet_result; - packet_result.receive_time = packet.arrival_time; - abs_send_timestamp_ += GetAbsoluteSendTimeDelta( - *packet.absolute_send_time_24bits, previous_abs_send_time_); - previous_abs_send_time_ = *packet.absolute_send_time_24bits; + packet_result.receive_time = packet.arrival_time(); + abs_send_timestamp_ += GetAbsoluteSendTimeDelta(*absolute_send_time_24bits, + previous_abs_send_time_); + previous_abs_send_time_ = *absolute_send_time_24bits; packet_result.sent_packet.send_time = abs_send_timestamp_; - packet_result.sent_packet.size = packet.size + packet_overhead_; + packet_result.sent_packet.size = + DataSize::Bytes(packet.size()) + packet_overhead_; packet_result.sent_packet.sequence_number = seq; network_state_estimator_->OnReceivedPacket(packet_result); } @@ -253,7 +215,7 @@ void RemoteEstimatorProxy::SendPeriodicFeedbacks() { packet_arrival_times_.end_sequence_number(); while (periodic_window_start_seq_ < packet_arrival_times_end_seq) { auto feedback_packet = MaybeBuildFeedbackPacket( - /*include_timestamps=*/true, periodic_window_start_seq_.value(), + /*include_timestamps=*/true, *periodic_window_start_seq_, packet_arrival_times_end_seq, /*is_periodic_update=*/true); @@ -317,7 +279,7 @@ RemoteEstimatorProxy::MaybeBuildFeedbackPacket( // Create the packet on demand, as it's not certain that there are packets // in the range that have been received. - std::unique_ptr feedback_packet = nullptr; + std::unique_ptr feedback_packet; int64_t next_sequence_number = begin_sequence_number_inclusive; @@ -333,20 +295,38 @@ RemoteEstimatorProxy::MaybeBuildFeedbackPacket( feedback_packet = std::make_unique(include_timestamps); feedback_packet->SetMediaSsrc(media_ssrc_); + + // It should be possible to add `seq` to this new `feedback_packet`, + // If difference between `seq` and `begin_sequence_number_inclusive`, + // is too large, discard reporting too old missing packets. + static constexpr int kMaxMissingSequenceNumbers = 0x7FFE; + int64_t base_sequence_number = std::max(begin_sequence_number_inclusive, + seq - kMaxMissingSequenceNumbers); + // Base sequence number is the expected first sequence number. This is // known, but we might not have actually received it, so the base time // shall be the time of the first received packet in the feedback. - feedback_packet->SetBase( - static_cast(begin_sequence_number_inclusive & 0xFFFF), - packet.arrival_time); + feedback_packet->SetBase(static_cast(base_sequence_number), + packet.arrival_time); feedback_packet->SetFeedbackSequenceNumber(feedback_packet_count_++); - } - if (!feedback_packet->AddReceivedPacket(static_cast(seq & 0xFFFF), - packet.arrival_time)) { - // Could not add timestamp, feedback packet might be full. Return and - // try again with a fresh packet. - break; + if (!feedback_packet->AddReceivedPacket(static_cast(seq), + packet.arrival_time)) { + // Could not add a single received packet to the feedback. + RTC_DCHECK_NOTREACHED() + << "Failed to create an RTCP transport feedback with base sequence " + "number " + << base_sequence_number << " and 1st received " << seq; + periodic_window_start_seq_ = seq; + return nullptr; + } + } else { + if (!feedback_packet->AddReceivedPacket(static_cast(seq), + packet.arrival_time)) { + // Could not add timestamp, feedback packet might be full. Return and + // try again with a fresh packet. + break; + } } next_sequence_number = seq + 1; diff --git a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h index a28e85c1a7a53..561410b0e0fb3 100644 --- a/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h +++ b/third_party/libwebrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h @@ -47,12 +47,6 @@ class RemoteEstimatorProxy { void IncomingPacket(const RtpPacketReceived& packet); - // TODO(perkj, bugs.webrtc.org/14859): Remove all usage. This method is - // currently not used by PeerConnections. - void IncomingPacket(int64_t arrival_time_ms, - size_t payload_size, - const RTPHeader& header); - // Sends periodic feedback if it is time to send it. // Returns time until next call to Process should be made. TimeDelta Process(Timestamp now); @@ -61,16 +55,6 @@ class RemoteEstimatorProxy { void SetTransportOverhead(DataSize overhead_per_packet); private: - struct Packet { - Timestamp arrival_time; - DataSize size; - uint32_t ssrc; - absl::optional absolute_send_time_24bits; - absl::optional transport_sequence_number; - absl::optional feedback_request; - }; - void IncomingPacket(Packet packet) RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_); - void MaybeCullOldPackets(int64_t sequence_number, Timestamp arrival_time) RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_); void SendPeriodicFeedbacks() RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_); diff --git a/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn b/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn index 6b599fc384786..4bc68ebf29e3a 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn +++ b/third_party/libwebrtc/modules/rtp_rtcp/BUILD.gn @@ -285,7 +285,6 @@ rtc_library("rtp_rtcp") { "../../api/rtc_event_log", "../../api/task_queue:pending_task_safety_flag", "../../api/task_queue:task_queue", - "../../api/transport:field_trial_based_config", "../../api/transport/rtp:dependency_descriptor", "../../api/transport/rtp:rtp_source", "../../api/units:data_rate", @@ -365,7 +364,6 @@ rtc_source_set("rtp_rtcp_legacy") { "../../api:rtp_headers", "../../api:transport_api", "../../api/rtc_event_log", - "../../api/transport:field_trial_based_config", "../../api/units:data_rate", "../../api/units:timestamp", "../../api/video:video_bitrate_allocation", @@ -640,6 +638,7 @@ if (rtc_include_tests) { "../../api:frame_transformer_factory", "../../api:libjingle_peerconnection_api", "../../api:mock_frame_encryptor", + "../../api:mock_transformable_video_frame", "../../api:rtp_headers", "../../api:rtp_packet_info", "../../api:rtp_parameters", @@ -648,7 +647,6 @@ if (rtc_include_tests) { "../../api:transport_api", "../../api/rtc_event_log", "../../api/task_queue", - "../../api/transport:field_trial_based_config", "../../api/transport/rtp:dependency_descriptor", "../../api/units:data_rate", "../../api/units:data_size", @@ -685,12 +683,10 @@ if (rtc_include_tests) { "../../rtc_base:timeutils", "../../system_wrappers", "../../test:explicit_key_value_config", - "../../test:field_trial", "../../test:mock_frame_transformer", "../../test:mock_transport", "../../test:rtp_test_utils", "../../test:run_loop", - "../../test:scoped_key_value_config", "../../test:test_support", "../../test/time_controller:time_controller", "../video_coding:codec_globals_headers", diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_receiver.h b/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_receiver.h index 29d9e72786135..b6a33882d18b7 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_receiver.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_receiver.h @@ -16,6 +16,7 @@ #include #include "api/sequence_checker.h" +#include "api/units/timestamp.h" #include "modules/rtp_rtcp/include/recovered_packet_receiver.h" #include "modules/rtp_rtcp/source/forward_error_correction.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" @@ -69,7 +70,8 @@ class FlexfecReceiver { // Logging and stats. Clock* const clock_; - int64_t last_recovered_packet_ms_ RTC_GUARDED_BY(sequence_checker_); + Timestamp last_recovered_packet_ RTC_GUARDED_BY(sequence_checker_) = + Timestamp::MinusInfinity(); FecPacketCounter packet_counter_ RTC_GUARDED_BY(sequence_checker_); RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_sender.h b/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_sender.h index f0acfe6c3db4a..b61781a480c2c 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_sender.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/include/flexfec_sender.h @@ -18,6 +18,7 @@ #include "absl/strings/string_view.h" #include "api/array_view.h" #include "api/rtp_parameters.h" +#include "api/units/timestamp.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_header_extension_size.h" @@ -77,7 +78,7 @@ class FlexfecSender : public VideoFecGenerator { // Utility. Clock* const clock_; Random random_; - int64_t last_generated_packet_ms_; + Timestamp last_generated_packet_ = Timestamp::MinusInfinity(); // Config. const int payload_type_; diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.cc b/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.cc index ec4d9d82e0c79..c2a37131dbd8d 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.cc @@ -12,32 +12,34 @@ namespace webrtc { -ReportBlockData::ReportBlockData() - : report_block_(), - report_block_timestamp_utc_us_(0), - last_rtt_ms_(0), - min_rtt_ms_(0), - max_rtt_ms_(0), - sum_rtt_ms_(0), - num_rtts_(0) {} - -double ReportBlockData::AvgRttMs() const { - return num_rtts_ ? static_cast(sum_rtt_ms_) / num_rtts_ : 0.0; +TimeDelta ReportBlockData::AvgRtt() const { + return num_rtts_ > 0 ? sum_rtt_ / num_rtts_ : TimeDelta::Zero(); } -void ReportBlockData::SetReportBlock(RTCPReportBlock report_block, - int64_t report_block_timestamp_utc_us) { - report_block_ = report_block; - report_block_timestamp_utc_us_ = report_block_timestamp_utc_us; +void ReportBlockData::SetReportBlock(uint32_t sender_ssrc, + const rtcp::ReportBlock& report_block, + Timestamp report_block_timestamp_utc) { + report_block_.sender_ssrc = sender_ssrc; + report_block_.source_ssrc = report_block.source_ssrc(); + report_block_.fraction_lost = report_block.fraction_lost(); + report_block_.packets_lost = report_block.cumulative_lost(); + report_block_.extended_highest_sequence_number = + report_block.extended_high_seq_num(); + report_block_.jitter = report_block.jitter(); + report_block_.delay_since_last_sender_report = + report_block.delay_since_last_sr(); + report_block_.last_sender_report_timestamp = report_block.last_sr(); + + report_block_timestamp_utc_ = report_block_timestamp_utc; } -void ReportBlockData::AddRoundTripTimeSample(int64_t rtt_ms) { - if (rtt_ms > max_rtt_ms_) - max_rtt_ms_ = rtt_ms; - if (num_rtts_ == 0 || rtt_ms < min_rtt_ms_) - min_rtt_ms_ = rtt_ms; - last_rtt_ms_ = rtt_ms; - sum_rtt_ms_ += rtt_ms; +void ReportBlockData::AddRoundTripTimeSample(TimeDelta rtt) { + if (rtt > max_rtt_) + max_rtt_ = rtt; + if (num_rtts_ == 0 || rtt < min_rtt_) + min_rtt_ = rtt; + last_rtt_ = rtt; + sum_rtt_ += rtt; ++num_rtts_; } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.h b/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.h index 2c4533ada8e0a..fa556cf8e7416 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/include/report_block_data.h @@ -11,40 +11,56 @@ #ifndef MODULES_RTP_RTCP_INCLUDE_REPORT_BLOCK_DATA_H_ #define MODULES_RTP_RTCP_INCLUDE_REPORT_BLOCK_DATA_H_ +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" namespace webrtc { class ReportBlockData { public: - ReportBlockData(); + ReportBlockData() = default; + + ReportBlockData(const ReportBlockData&) = default; + ReportBlockData& operator=(const ReportBlockData&) = default; const RTCPReportBlock& report_block() const { return report_block_; } - int64_t report_block_timestamp_utc_us() const { - return report_block_timestamp_utc_us_; + + [[deprecated]] int64_t report_block_timestamp_utc_us() const { + return report_block_timestamp_utc_.us(); } - int64_t last_rtt_ms() const { return last_rtt_ms_; } - int64_t min_rtt_ms() const { return min_rtt_ms_; } - int64_t max_rtt_ms() const { return max_rtt_ms_; } - int64_t sum_rtt_ms() const { return sum_rtt_ms_; } + [[deprecated]] int64_t last_rtt_ms() const { return last_rtt_.ms(); } + [[deprecated]] int64_t min_rtt_ms() const { return min_rtt_.ms(); } + [[deprecated]] int64_t max_rtt_ms() const { return max_rtt_.ms(); } + [[deprecated]] int64_t sum_rtt_ms() const { return sum_rtt_.ms(); } + [[deprecated]] double AvgRttMs() const { return AvgRtt().ms(); } + + Timestamp report_block_timestamp_utc() const { + return report_block_timestamp_utc_; + } + TimeDelta last_rtt() const { return last_rtt_; } + TimeDelta min_rtt() const { return min_rtt_; } + TimeDelta max_rtt() const { return max_rtt_; } + TimeDelta sum_rtts() const { return sum_rtt_; } size_t num_rtts() const { return num_rtts_; } bool has_rtt() const { return num_rtts_ != 0; } - double AvgRttMs() const; + TimeDelta AvgRtt() const; - void SetReportBlock(RTCPReportBlock report_block, - int64_t report_block_timestamp_utc_us); - void AddRoundTripTimeSample(int64_t rtt_ms); + void SetReportBlock(uint32_t sender_ssrc, + const rtcp::ReportBlock& report_block, + Timestamp report_block_timestamp_utc_us); + void AddRoundTripTimeSample(TimeDelta rtt); private: RTCPReportBlock report_block_; - int64_t report_block_timestamp_utc_us_; - - int64_t last_rtt_ms_; - int64_t min_rtt_ms_; - int64_t max_rtt_ms_; - int64_t sum_rtt_ms_; - size_t num_rtts_; + Timestamp report_block_timestamp_utc_ = Timestamp::Zero(); + TimeDelta last_rtt_ = TimeDelta::Zero(); + TimeDelta min_rtt_ = TimeDelta::Zero(); + TimeDelta max_rtt_ = TimeDelta::Zero(); + TimeDelta sum_rtt_ = TimeDelta::Zero(); + size_t num_rtts_ = 0; }; class ReportBlockDataObserver { diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc index 2e7e219f94227..be19c186ccdc6 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc @@ -15,7 +15,6 @@ #include #include "absl/strings/match.h" -#include "api/transport/field_trial_based_config.h" #include "api/units/timestamp.h" #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h" diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_receiver.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_receiver.cc index bd67de1f8302b..d852c32e3ceaf 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_receiver.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_receiver.cc @@ -14,6 +14,8 @@ #include "api/array_view.h" #include "api/scoped_refptr.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" @@ -25,7 +27,7 @@ namespace { constexpr size_t kMinFlexfecHeaderSize = 20; // How often to log the recovered packets to the text log. -constexpr int kPacketLogIntervalMs = 10000; +constexpr TimeDelta kPacketLogInterval = TimeDelta::Seconds(10); } // namespace @@ -50,8 +52,7 @@ FlexfecReceiver::FlexfecReceiver( erasure_code_( ForwardErrorCorrection::CreateFlexfec(ssrc, protected_media_ssrc)), recovered_packet_receiver_(recovered_packet_receiver), - clock_(clock), - last_recovered_packet_ms_(-1) { + clock_(clock) { // It's OK to create this object on a different thread/task queue than // the one used during main operation. sequence_checker_.Detach(); @@ -175,9 +176,9 @@ void FlexfecReceiver::ProcessReceivedPacket( recovered_packet_receiver_->OnRecoveredPacket(parsed_packet); // Periodically log the incoming packets at LS_INFO. - int64_t now_ms = clock_->TimeInMilliseconds(); + Timestamp now = clock_->CurrentTime(); bool should_log_periodically = - now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs; + now - last_recovered_packet_ > kPacketLogInterval; if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE) || should_log_periodically) { rtc::LoggingSeverity level = should_log_periodically ? rtc::LS_INFO : rtc::LS_VERBOSE; @@ -187,7 +188,7 @@ void FlexfecReceiver::ProcessReceivedPacket( << recovered_packet->pkt->data.size() << " from FlexFEC stream with SSRC: " << ssrc_; if (should_log_periodically) { - last_recovered_packet_ms_ = now_ms; + last_recovered_packet_ = now; } } } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_sender.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_sender.cc index 292fe4a8dd566..c8bac0114d766 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_sender.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/flexfec_sender.cc @@ -16,6 +16,8 @@ #include #include "absl/strings/string_view.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/forward_error_correction.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" @@ -42,7 +44,7 @@ constexpr size_t kFlexfecMaxHeaderSize = 32; const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000; // How often to log the generated FEC packets to the text log. -constexpr int64_t kPacketLogIntervalMs = 10000; +constexpr TimeDelta kPacketLogInterval = TimeDelta::Seconds(10); RtpHeaderExtensionMap RegisterSupportedExtensions( const std::vector& rtp_header_extensions) { @@ -79,7 +81,6 @@ FlexfecSender::FlexfecSender( Clock* clock) : clock_(clock), random_(clock_->TimeInMicroseconds()), - last_generated_packet_ms_(-1), payload_type_(payload_type), // Reset RTP state if this is not the first time we are operating. // Otherwise, randomize the initial timestamp offset and RTP sequence @@ -168,17 +169,17 @@ std::vector> FlexfecSender::GetFecPackets() { ulpfec_generator_.ResetState(); } - int64_t now_ms = clock_->TimeInMilliseconds(); + Timestamp now = clock_->CurrentTime(); if (!fec_packets_to_send.empty() && - now_ms - last_generated_packet_ms_ > kPacketLogIntervalMs) { + now - last_generated_packet_ > kPacketLogInterval) { RTC_LOG(LS_VERBOSE) << "Generated " << fec_packets_to_send.size() << " FlexFEC packets with payload type: " << payload_type_ << " and SSRC: " << ssrc_ << "."; - last_generated_packet_ms_ = now_ms; + last_generated_packet_ = now; } MutexLock lock(&mutex_); - fec_bitrate_.Update(total_fec_data_bytes, now_ms); + fec_bitrate_.Update(total_fec_data_bytes, now.ms()); return fec_packets_to_send; } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc index 869e1cc5bf054..db830a9a2e2f2 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc @@ -15,7 +15,6 @@ #include "absl/algorithm/container.h" #include "api/call/transport.h" -#include "api/transport/field_trial_based_config.h" #include "call/rtp_stream_receiver_controller.h" #include "call/rtx_receive_stream.h" #include "modules/rtp_rtcp/include/receive_statistics.h" @@ -25,6 +24,7 @@ #include "modules/rtp_rtcp/source/rtp_sender_video.h" #include "rtc_base/rate_limiter.h" #include "rtc_base/thread.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" namespace webrtc { @@ -138,7 +138,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test { configuration.local_media_ssrc = kTestSsrc; configuration.rtx_send_ssrc = kTestRtxSsrc; rtp_rtcp_module_ = ModuleRtpRtcpImpl2::Create(configuration); - FieldTrialBasedConfig field_trials; + test::ExplicitKeyValueConfig field_trials(""); RTPSenderVideo::Config video_config; video_config.clock = &fake_clock; video_config.rtp_sender = rtp_rtcp_module_->RtpSender(); diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc index 1dc756d876298..7c6c2cf443a4b 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc @@ -33,7 +33,8 @@ constexpr int64_t kStatisticsProcessIntervalMs = 1000; StreamStatistician::~StreamStatistician() {} -StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc, Clock* clock, +StreamStatisticianImpl::StreamStatisticianImpl(uint32_t ssrc, + Clock* clock, int max_reordering_threshold) : ssrc_(ssrc), clock_(clock), diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc index 92c8f34196c57..b6593a4c3b813 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc @@ -285,7 +285,7 @@ TEST_P(ReceiveStatisticsTest, SimpleLossComputation) { // 20% = 51/255. EXPECT_EQ(51u, report_blocks[0].fraction_lost()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); EXPECT_EQ(20, statistician->GetFractionLostInPercent()); @@ -308,7 +308,7 @@ TEST_P(ReceiveStatisticsTest, LossComputationWithReordering) { // 20% = 51/255. EXPECT_EQ(51u, report_blocks[0].fraction_lost()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); EXPECT_EQ(20, statistician->GetFractionLostInPercent()); @@ -333,7 +333,7 @@ TEST_P(ReceiveStatisticsTest, LossComputationWithDuplicates) { // 20% = 51/255. EXPECT_EQ(51u, report_blocks[0].fraction_lost()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); EXPECT_EQ(20, statistician->GetFractionLostInPercent()); @@ -359,7 +359,7 @@ TEST_P(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) { // 20% = 51/255. EXPECT_EQ(51u, report_blocks[0].fraction_lost()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); EXPECT_EQ(20, statistician->GetFractionLostInPercent()); @@ -374,7 +374,7 @@ TEST_P(ReceiveStatisticsTest, LossComputationWithSequenceNumberWrapping) { // 50% = 127/255. EXPECT_EQ(127u, report_blocks[0].fraction_lost()); - EXPECT_EQ(2, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(2, report_blocks[0].cumulative_lost()); // 2 packets lost, 7 expected EXPECT_EQ(28, statistician->GetFractionLostInPercent()); } @@ -396,7 +396,7 @@ TEST_P(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc()); EXPECT_EQ(0, report_blocks[0].fraction_lost()); - EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(0, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); EXPECT_EQ(0, statistician->GetFractionLostInPercent()); @@ -408,7 +408,7 @@ TEST_P(ReceiveStatisticsTest, StreamRestartDoesntCountAsLoss) { EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc()); EXPECT_EQ(0, report_blocks[0].fraction_lost()); - EXPECT_EQ(0, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(0, report_blocks[0].cumulative_lost()); EXPECT_EQ(0, statistician->GetFractionLostInPercent()); } @@ -432,7 +432,7 @@ TEST_P(ReceiveStatisticsTest, CountsLossAfterStreamRestart) { ASSERT_THAT(report_blocks, SizeIs(1)); EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); StreamStatistician* statistician = receive_statistics_->GetStatistician(kSsrc1); @@ -460,7 +460,7 @@ TEST_P(ReceiveStatisticsTest, StreamCanRestartAtSequenceNumberWrapAround) { ASSERT_THAT(report_blocks, SizeIs(1)); EXPECT_EQ(kSsrc1, report_blocks[0].source_ssrc()); - EXPECT_EQ(1, report_blocks[0].cumulative_lost_signed()); + EXPECT_EQ(1, report_blocks[0].cumulative_lost()); } TEST_P(ReceiveStatisticsTest, StreamRestartNeedsTwoConsecutivePackets) { diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc index 23ea49622b01c..47f8eb13cb9da 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report_unittest.cc @@ -51,7 +51,7 @@ TEST(RtcpPacketReceiverReportTest, ParseWithOneReportBlock) { const ReportBlock& rb = parsed.report_blocks().front(); EXPECT_EQ(kRemoteSsrc, rb.source_ssrc()); EXPECT_EQ(kFractionLost, rb.fraction_lost()); - EXPECT_EQ(kCumulativeLost, rb.cumulative_lost_signed()); + EXPECT_EQ(kCumulativeLost, rb.cumulative_lost()); EXPECT_EQ(kExtHighestSeqNum, rb.extended_high_seq_num()); EXPECT_EQ(kJitter, rb.jitter()); EXPECT_EQ(kLastSr, rb.last_sr()); diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc index d4579fc8d652c..e7e92d2bf1c64 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.cc @@ -65,12 +65,11 @@ bool ReportBlock::Parse(const uint8_t* buffer, size_t length) { void ReportBlock::Create(uint8_t* buffer) const { // Runtime check should be done while setting cumulative_lost. - RTC_DCHECK_LT(cumulative_lost_signed(), - (1 << 23)); // Have only 3 bytes for it. + RTC_DCHECK_LT(cumulative_lost(), (1 << 23)); // Have only 3 bytes for it. ByteWriter::WriteBigEndian(&buffer[0], source_ssrc()); ByteWriter::WriteBigEndian(&buffer[4], fraction_lost()); - ByteWriter::WriteBigEndian(&buffer[5], cumulative_lost_signed()); + ByteWriter::WriteBigEndian(&buffer[5], cumulative_lost()); ByteWriter::WriteBigEndian(&buffer[8], extended_high_seq_num()); ByteWriter::WriteBigEndian(&buffer[12], jitter()); ByteWriter::WriteBigEndian(&buffer[16], last_sr()); @@ -88,13 +87,5 @@ bool ReportBlock::SetCumulativeLost(int32_t cumulative_lost) { return true; } -uint32_t ReportBlock::cumulative_lost() const { - if (cumulative_lost_ < 0) { - RTC_LOG(LS_VERBOSE) << "Ignoring negative value of cumulative_lost"; - return 0; - } - return cumulative_lost_; -} - } // namespace rtcp } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h index eb16640ae2873..b49219eceb81c 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block.h @@ -49,9 +49,7 @@ class ReportBlock { uint32_t source_ssrc() const { return source_ssrc_; } uint8_t fraction_lost() const { return fraction_lost_; } - int32_t cumulative_lost_signed() const { return cumulative_lost_; } - // Deprecated - returns max(0, cumulative_lost_), not negative values. - uint32_t cumulative_lost() const; + int32_t cumulative_lost() const { return cumulative_lost_; } uint32_t extended_high_seq_num() const { return extended_high_seq_num_; } uint32_t jitter() const { return jitter_; } uint32_t last_sr() const { return last_sr_; } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc index 5cc102fed0a99..11031a059aa1f 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc @@ -68,7 +68,7 @@ TEST(RtcpPacketReportBlockTest, ParseMatchCreate) { EXPECT_EQ(kRemoteSsrc, parsed.source_ssrc()); EXPECT_EQ(kFractionLost, parsed.fraction_lost()); - EXPECT_EQ(kCumulativeLost, parsed.cumulative_lost_signed()); + EXPECT_EQ(kCumulativeLost, parsed.cumulative_lost()); EXPECT_EQ(kExtHighestSeqNum, parsed.extended_high_seq_num()); EXPECT_EQ(kJitter, parsed.jitter()); EXPECT_EQ(kLastSr, parsed.last_sr()); @@ -77,9 +77,6 @@ TEST(RtcpPacketReportBlockTest, ParseMatchCreate) { TEST(RtcpPacketReportBlockTest, ValidateCumulativeLost) { // CumulativeLost is a signed 24-bit integer. - // However, existing code expects it to be an unsigned integer. - // The case of negative values should be unusual; we return 0 - // when caller wants an unsigned integer. const int32_t kMaxCumulativeLost = 0x7fffff; const int32_t kMinCumulativeLost = -0x800000; ReportBlock rb; @@ -87,8 +84,7 @@ TEST(RtcpPacketReportBlockTest, ValidateCumulativeLost) { EXPECT_TRUE(rb.SetCumulativeLost(kMaxCumulativeLost)); EXPECT_FALSE(rb.SetCumulativeLost(kMinCumulativeLost - 1)); EXPECT_TRUE(rb.SetCumulativeLost(kMinCumulativeLost)); - EXPECT_EQ(kMinCumulativeLost, rb.cumulative_lost_signed()); - EXPECT_EQ(0u, rb.cumulative_lost()); + EXPECT_EQ(rb.cumulative_lost(), kMinCumulativeLost); } TEST(RtcpPacketReportBlockTest, ParseNegativeCumulativeLost) { @@ -103,7 +99,7 @@ TEST(RtcpPacketReportBlockTest, ParseNegativeCumulativeLost) { ReportBlock parsed; EXPECT_TRUE(parsed.Parse(buffer, kBufferLength)); - EXPECT_EQ(kNegativeCumulativeLost, parsed.cumulative_lost_signed()); + EXPECT_EQ(kNegativeCumulativeLost, parsed.cumulative_lost()); } } // namespace diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver.cc index 3cbbb915fee77..8e178da67dbc1 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -619,33 +619,23 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block, if (!registered_ssrcs_.contains(report_block.source_ssrc())) return; - last_received_rb_ = clock_->CurrentTime(); + Timestamp now = clock_->CurrentTime(); + last_received_rb_ = now; ReportBlockData* report_block_data = &received_report_blocks_[report_block.source_ssrc()]; - RTCPReportBlock rtcp_report_block; - rtcp_report_block.sender_ssrc = remote_ssrc; - rtcp_report_block.source_ssrc = report_block.source_ssrc(); - rtcp_report_block.fraction_lost = report_block.fraction_lost(); - rtcp_report_block.packets_lost = report_block.cumulative_lost_signed(); if (report_block.extended_high_seq_num() > report_block_data->report_block().extended_highest_sequence_number) { // We have successfully delivered new RTP packets to the remote side after // the last RR was sent from the remote side. last_increased_sequence_number_ = last_received_rb_; } - rtcp_report_block.extended_highest_sequence_number = - report_block.extended_high_seq_num(); - rtcp_report_block.jitter = report_block.jitter(); - rtcp_report_block.delay_since_last_sender_report = - report_block.delay_since_last_sr(); - rtcp_report_block.last_sender_report_timestamp = report_block.last_sr(); + NtpTime now_ntp = clock_->ConvertTimestampToNtpTime(now); // Number of seconds since 1900 January 1 00:00 GMT (see // https://tools.ietf.org/html/rfc868). report_block_data->SetReportBlock( - rtcp_report_block, - (clock_->CurrentNtpInMilliseconds() - rtc::kNtpJan1970Millisecs) * - rtc::kNumMicrosecsPerMillisec); + remote_ssrc, report_block, + Timestamp::Millis(now_ntp.ToMs() - rtc::kNtpJan1970Millisecs)); uint32_t send_time_ntp = report_block.last_sr(); // RFC3550, section 6.4.1, LSR field discription states: @@ -655,14 +645,13 @@ void RTCPReceiver::HandleReportBlock(const ReportBlock& report_block, if (send_time_ntp != 0) { uint32_t delay_ntp = report_block.delay_since_last_sr(); // Local NTP time. - uint32_t receive_time_ntp = - CompactNtp(clock_->ConvertTimestampToNtpTime(last_received_rb_)); + uint32_t receive_time_ntp = CompactNtp(now_ntp); // RTT in 1/(2^16) seconds. uint32_t rtt_ntp = receive_time_ntp - delay_ntp - send_time_ntp; // Convert to 1/1000 seconds (milliseconds). TimeDelta rtt = CompactNtpRttToTimeDelta(rtt_ntp); - report_block_data->AddRoundTripTimeSample(rtt.ms()); + report_block_data->AddRoundTripTimeSample(rtt); if (report_block.source_ssrc() == local_media_ssrc()) { rtts_[remote_ssrc].AddRtt(rtt); } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc index b64363a87ca00..979609ab403ba 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc @@ -549,15 +549,14 @@ TEST(RtcpReceiverTest, EXPECT_THAT( receiver.GetLatestReportBlockData(), - UnorderedElementsAre( - Property( - &ReportBlockData::report_block, - AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc), - Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2), - Field(&RTCPReportBlock::fraction_lost, kFracLost[1]), - Field(&RTCPReportBlock::packets_lost, kCumLost[1]), - Field(&RTCPReportBlock::extended_highest_sequence_number, - kSequenceNumbers[1]))))); + UnorderedElementsAre(Property( + &ReportBlockData::report_block, + AllOf(Field(&RTCPReportBlock::source_ssrc, kReceiverMainSsrc), + Field(&RTCPReportBlock::sender_ssrc, kSenderSsrc2), + Field(&RTCPReportBlock::fraction_lost, kFracLost[1]), + Field(&RTCPReportBlock::packets_lost, kCumLost[1]), + Field(&RTCPReportBlock::extended_highest_sequence_number, + kSequenceNumbers[1]))))); } TEST(RtcpReceiverTest, GetRtt) { @@ -1579,13 +1578,12 @@ TEST(RtcpReceiverTest, EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc); EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc); EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost); - EXPECT_EQ(rtcp_block.cumulative_lost_signed(), - report_block.packets_lost); + EXPECT_EQ(rtcp_block.cumulative_lost(), report_block.packets_lost); EXPECT_EQ(rtcp_block.extended_high_seq_num(), report_block.extended_highest_sequence_number); EXPECT_EQ(rtcp_block.jitter(), report_block.jitter); - EXPECT_EQ(kNtpNowMs * rtc::kNumMicrosecsPerMillisec, - report_block_data.report_block_timestamp_utc_us()); + EXPECT_EQ(report_block_data.report_block_timestamp_utc(), + Timestamp::Millis(kNtpNowMs)); // No RTT is calculated in this test. EXPECT_EQ(0u, report_block_data.num_rtts()); }); @@ -1602,8 +1600,12 @@ TEST(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) { RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl); receiver.SetRemoteSSRC(kSenderSsrc); - const TimeDelta kRtt = TimeDelta::Millis(120); - const uint32_t kDelayNtp = 123000; + // To avoid issues with rounding due to different way to represent time units, + // use RTT that can be precisly represented both with + // TimeDelta units (i.e. integer number of microseconds), and + // ntp units (i.e. integer number of 2^(-32) seconds) + const TimeDelta kRtt = TimeDelta::Millis(125); + const uint32_t kDelayNtp = 123'000; const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp); uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime()); @@ -1628,10 +1630,10 @@ TEST(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) { EXPECT_EQ(kReceiverMainSsrc, report_block_data.report_block().source_ssrc); EXPECT_EQ(1u, report_block_data.num_rtts()); - EXPECT_EQ(kRtt.ms(), report_block_data.min_rtt_ms()); - EXPECT_EQ(kRtt.ms(), report_block_data.max_rtt_ms()); - EXPECT_EQ(kRtt.ms(), report_block_data.sum_rtt_ms()); - EXPECT_EQ(kRtt.ms(), report_block_data.last_rtt_ms()); + EXPECT_EQ(kRtt, report_block_data.min_rtt()); + EXPECT_EQ(kRtt, report_block_data.max_rtt()); + EXPECT_EQ(kRtt, report_block_data.sum_rtts()); + EXPECT_EQ(kRtt, report_block_data.last_rtt()); }); EXPECT_CALL(observer, OnReportBlockDataUpdated) .WillOnce([](ReportBlockData report_block_data) { diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc index ae59dc5b0c305..0a07ab26c5ff8 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtcp_sender_unittest.cc @@ -280,7 +280,7 @@ TEST_F(RtcpSenderTest, SendRrWithOneReportBlock) { const rtcp::ReportBlock& rb = parser()->receiver_report()->report_blocks()[0]; EXPECT_EQ(kRemoteSsrc, rb.source_ssrc()); EXPECT_EQ(0U, rb.fraction_lost()); - EXPECT_EQ(0, rb.cumulative_lost_signed()); + EXPECT_EQ(0, rb.cumulative_lost()); EXPECT_EQ(kSeqNum, rb.extended_high_seq_num()); } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc index 974557ce6eb8f..148e4f973b808 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_dependency_descriptor_extension_unittest.cc @@ -13,7 +13,6 @@ #include "api/array_view.h" #include "api/transport/rtp/dependency_descriptor.h" #include "common_video/generic_frame_descriptor/generic_frame_info.h" - #include "test/gmock.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packet_received.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packet_received.h index f290a643a44c2..51bd17d7bfbe9 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packet_received.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packet_received.h @@ -39,8 +39,8 @@ class RtpPacketReceived : public RtpPacket { ~RtpPacketReceived(); - // TODO(danilchap): Remove this function when all code update to use RtpPacket - // directly. Function is there just for easier backward compatibilty. + // TODO(bugs.webrtc.org/15054): Remove this function when all code is updated + // to use RtpPacket directly. void GetHeader(RTPHeader* header) const; // Time in local time base as close as it can to packet arrived on the diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index eb0acddefab2b..4aa4b1aab5e2c 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -21,7 +21,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" -#include "api/transport/field_trial_based_config.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_sender.h" #include "modules/rtp_rtcp/source/rtp_rtcp_config.h" diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc index 1e01861665972..016d27db5d6f5 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc @@ -22,7 +22,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/sequence_checker.h" -#include "api/transport/field_trial_based_config.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc index 5987b01302166..9f3dd37d86ee3 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc @@ -14,13 +14,13 @@ #include #include -#include "api/transport/field_trial_based_config.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_packet.h" #include "modules/rtp_rtcp/source/rtcp_packet/nack.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_sender_video.h" #include "rtc_base/rate_limiter.h" +#include "test/explicit_key_value_config.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" @@ -187,7 +187,7 @@ class RtpRtcpImplTest : public ::testing::Test { sender_.impl_->SetSequenceNumber(kSequenceNumber); sender_.impl_->SetStorePacketsStatus(true, 100); - FieldTrialBasedConfig field_trials; + test::ExplicitKeyValueConfig field_trials(""); RTPSenderVideo::Config video_config; video_config.clock = &clock_; video_config.rtp_sender = sender_.impl_->RtpSender(); diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h index d7b0d3d1c8870..776d36efbcd78 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_rtcp_interface.h @@ -125,8 +125,7 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { // done by RTCP RR acking. bool always_send_mid_and_rid = false; - // If set, field trials are read from `field_trials`, otherwise - // defaults to webrtc::FieldTrialBasedConfig. + // If set, field trials are read from `field_trials`. const FieldTrialsView* field_trials = nullptr; // SSRCs for media and retransmission, respectively. diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc index 244f644bd1a1e..47b7b7910bd6a 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc @@ -47,18 +47,12 @@ namespace { RTC_CHECK_NOTREACHED(); } -constexpr char kIncludeCaptureClockOffset[] = - "WebRTC-IncludeCaptureClockOffset"; - } // namespace RTPSenderAudio::RTPSenderAudio(Clock* clock, RTPSender* rtp_sender) : clock_(clock), rtp_sender_(rtp_sender), - absolute_capture_time_sender_(clock), - include_capture_clock_offset_( - !absl::StartsWith(field_trials_.Lookup(kIncludeCaptureClockOffset), - "Disabled")) { + absolute_capture_time_sender_(clock) { RTC_DCHECK(clock_); } @@ -284,8 +278,7 @@ bool RTPSenderAudio::SendAudio(AudioFrameType frame_type, encoder_rtp_timestamp_frequency.value_or(0), Int64MsToUQ32x32(clock_->ConvertTimestampToNtpTimeInMilliseconds( absolute_capture_timestamp_ms)), - /*estimated_capture_clock_offset=*/ - include_capture_clock_offset_ ? absl::make_optional(0) : absl::nullopt); + /*estimated_capture_clock_offset=*/0); if (absolute_capture_time) { // It also checks that extension was registered during SDP negotiation. If // not then setter won't do anything. diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.h index d40fee6386084..e22ca41b90261 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio.h @@ -17,7 +17,6 @@ #include #include "absl/strings/string_view.h" -#include "api/transport/field_trial_based_config.h" #include "modules/audio_coding/include/audio_coding_module_typedefs.h" #include "modules/rtp_rtcp/source/absolute_capture_time_sender.h" #include "modules/rtp_rtcp/source/dtmf_queue.h" @@ -112,9 +111,6 @@ class RTPSenderAudio { RTC_GUARDED_BY(send_audio_mutex_); AbsoluteCaptureTimeSender absolute_capture_time_sender_; - - const FieldTrialBasedConfig field_trials_; - const bool include_capture_clock_offset_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio_unittest.cc index 7397a3ac4e864..b497b5562cf98 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_audio_unittest.cc @@ -13,14 +13,12 @@ #include #include -#include "api/transport/field_trial_based_config.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" #include "rtc_base/thread.h" -#include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" @@ -150,41 +148,6 @@ TEST_F(RtpSenderAudioTest, SendAudioWithoutAbsoluteCaptureTime) { .HasExtension()); } -// Essentially the same test as -// SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset but with a field -// trial. We will remove this test eventually. -TEST_F(RtpSenderAudioTest, SendAudioWithAbsoluteCaptureTime) { - // Recreate rtp_sender_audio_ with new field trial. - test::ScopedFieldTrials field_trial( - "WebRTC-IncludeCaptureClockOffset/Disabled/"); - rtp_sender_audio_ = - std::make_unique(&fake_clock_, rtp_module_->RtpSender()); - - rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(), - kAbsoluteCaptureTimeExtensionId); - constexpr uint32_t kAbsoluteCaptureTimestampMs = 521; - const char payload_name[] = "audio"; - const uint8_t payload_type = 127; - ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload( - payload_name, payload_type, 48000, 0, 1500)); - uint8_t payload[] = {47, 11, 32, 93, 89}; - - ASSERT_TRUE(rtp_sender_audio_->SendAudio( - AudioFrameType::kAudioFrameCN, payload_type, 4321, payload, - sizeof(payload), kAbsoluteCaptureTimestampMs)); - - auto absolute_capture_time = - transport_.last_sent_packet() - .GetExtension(); - EXPECT_TRUE(absolute_capture_time); - EXPECT_EQ( - absolute_capture_time->absolute_capture_timestamp, - Int64MsToUQ32x32(fake_clock_.ConvertTimestampToNtpTimeInMilliseconds( - kAbsoluteCaptureTimestampMs))); - EXPECT_FALSE( - absolute_capture_time->estimated_capture_clock_offset.has_value()); -} - TEST_F(RtpSenderAudioTest, SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset) { rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(), @@ -203,14 +166,12 @@ TEST_F(RtpSenderAudioTest, auto absolute_capture_time = transport_.last_sent_packet() .GetExtension(); - EXPECT_TRUE(absolute_capture_time); + ASSERT_TRUE(absolute_capture_time); EXPECT_EQ( absolute_capture_time->absolute_capture_timestamp, Int64MsToUQ32x32(fake_clock_.ConvertTimestampToNtpTimeInMilliseconds( kAbsoluteCaptureTimestampMs))); - EXPECT_TRUE( - absolute_capture_time->estimated_capture_clock_offset.has_value()); - EXPECT_EQ(0, *absolute_capture_time->estimated_capture_clock_offset); + EXPECT_EQ(absolute_capture_time->estimated_capture_clock_offset, 0); } // As RFC4733, named telephone events are carried as part of the audio stream diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc index 7931dd824df4e..a9fa0713795fc 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_egress.cc @@ -16,7 +16,6 @@ #include #include "absl/strings/match.h" -#include "api/transport/field_trial_based_config.h" #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" #include "rtc_base/logging.h" diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index ff6a3725fa30e..70cd3382e3e00 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -15,7 +15,6 @@ #include "absl/strings/string_view.h" #include "api/rtc_event_log/rtc_event.h" -#include "api/transport/field_trial_based_config.h" #include "api/video/video_codec_constants.h" #include "api/video/video_timing.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" @@ -36,11 +35,10 @@ #include "rtc_base/logging.h" #include "rtc_base/rate_limiter.h" #include "rtc_base/strings/string_builder.h" -#include "test/field_trial.h" +#include "test/explicit_key_value_config.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_transport.h" -#include "test/scoped_key_value_config.h" #include "test/time_controller/simulated_time_controller.h" namespace webrtc { @@ -172,7 +170,7 @@ class RtpSenderTest : public ::testing::Test { std::unique_ptr packet_history_; std::unique_ptr rtp_sender_; - const test::ScopedKeyValueConfig field_trials_; + const test::ExplicitKeyValueConfig field_trials_{""}; std::unique_ptr BuildRtpPacket(int payload_type, bool marker_bit, diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.cc index 14031f137e622..adc53d22437ff 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -46,8 +46,6 @@ namespace webrtc { namespace { constexpr size_t kRedForFecHeaderLength = 1; constexpr int64_t kMaxUnretransmittableFrameIntervalMs = 33 * 4; -constexpr char kIncludeCaptureClockOffset[] = - "WebRTC-IncludeCaptureClockOffset"; void BuildRedPayload(const RtpPacketToSend& media_packet, RtpPacketToSend* red_packet) { @@ -173,10 +171,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) rtp_sender_->Csrcs(), rtp_sender_->Rid(), config.task_queue_factory) - : nullptr), - include_capture_clock_offset_(!absl::StartsWith( - config.field_trials->Lookup(kIncludeCaptureClockOffset), - "Disabled")) { + : nullptr) { if (frame_transformer_delegate_) frame_transformer_delegate_->Init(); } @@ -573,9 +568,7 @@ bool RTPSenderVideo::SendVideo( video_header.absolute_capture_time->absolute_capture_timestamp = Int64MsToUQ32x32( clock_->ConvertTimestampToNtpTime(*capture_time).ToMs()); - if (include_capture_clock_offset_) { - video_header.absolute_capture_time->estimated_capture_clock_offset = 0; - } + video_header.absolute_capture_time->estimated_capture_clock_offset = 0; } // Let `absolute_capture_time_sender_` decide if the extension should be sent. diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.h b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.h index d9474f3db517c..a1388a8b6d053 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video.h @@ -254,8 +254,6 @@ class RTPSenderVideo : public RTPVideoFrameSenderInterface { const rtc::scoped_refptr frame_transformer_delegate_; - - const bool include_capture_clock_offset_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc index 1d2c880c8d7a2..79ceae5209e74 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc @@ -45,7 +45,6 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { expected_retransmission_time_ms_(expected_retransmission_time_ms), ssrc_(ssrc), csrcs_(csrcs), - metadata_(Metadata()), rid_(rid) { RTC_DCHECK_GE(payload_type_, 0); RTC_DCHECK_LE(payload_type_, 127); @@ -69,8 +68,6 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { return frame_type_ == VideoFrameType::kVideoFrameKey; } - const VideoFrameMetadata& GetMetadata() const override { return metadata_; } - VideoFrameMetadata Metadata() const override { VideoFrameMetadata metadata = header_.GetAsMetadata(); metadata.SetSsrc(ssrc_); @@ -82,9 +79,6 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { header_.SetFromMetadata(metadata); ssrc_ = metadata.GetSsrc(); csrcs_ = metadata.GetCsrcs(); - // Cache a copy to allow GetMetadata() to return references. - // TODO(crbug.com/webrtc/14709): Remove once GetMetadata() is removed. - metadata_ = Metadata(); } const RTPVideoHeader& GetHeader() const { return header_; } @@ -116,12 +110,6 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { uint32_t ssrc_; std::vector csrcs_; - - // This is a copy of the value returned by `Metadata()`, only needed because - // the interface says GetMetadata() must return a const ref rather than a - // value. - // TODO(crbug.com/webrtc/14709): Delete once GetMetdata() is removed. - VideoFrameMetadata metadata_; const std::string rid_; }; } // namespace @@ -191,7 +179,7 @@ void RTPSenderVideoFrameTransformerDelegate::SendVideo( transformed_video_frame->GetData(), transformed_video_frame->GetHeader(), transformed_video_frame->GetExpectedRetransmissionTimeMs(), - transformed_video_frame->GetMetadata().GetCsrcs()); + transformed_video_frame->Metadata().GetCsrcs()); } void RTPSenderVideoFrameTransformerDelegate::SetVideoStructureUnderLock( diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc index 25d6716302197..683d082099aee 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc @@ -16,13 +16,11 @@ #include #include "absl/memory/memory.h" -#include "api/field_trials_registry.h" #include "api/frame_transformer_factory.h" #include "api/rtp_headers.h" #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/transport/field_trial_based_config.h" #include "api/transport/rtp/dependency_descriptor.h" #include "api/units/timestamp.h" #include "api/video/video_codec_constants.h" @@ -45,6 +43,7 @@ #include "rtc_base/logging.h" #include "rtc_base/rate_limiter.h" #include "rtc_base/thread.h" +#include "test/explicit_key_value_config.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_frame_transformer.h" @@ -156,25 +155,6 @@ class TestRtpSenderVideo : public RTPSenderVideo { } }; -class FieldTrials : public FieldTrialsRegistry { - public: - FieldTrials() : include_capture_clock_offset_(false) {} - - void set_include_capture_clock_offset(bool include_capture_clock_offset) { - include_capture_clock_offset_ = include_capture_clock_offset; - } - - private: - std::string GetValue(absl::string_view key) const override { - if (key == "WebRTC-IncludeCaptureClockOffset") { - return include_capture_clock_offset_ ? "" : "Disabled"; - } - return ""; - } - - bool include_capture_clock_offset_; -}; - class RtpSenderVideoTest : public ::testing::Test { public: RtpSenderVideoTest() @@ -205,7 +185,7 @@ class RtpSenderVideoTest : public ::testing::Test { protected: rtc::AutoThread main_thread_; const RtpRtcpInterface::Configuration config_; - FieldTrials field_trials_; + test::ExplicitKeyValueConfig field_trials_{""}; SimulatedClock fake_clock_; LoopbackTransportTest transport_; RateLimiter retransmission_rate_limiter_; @@ -1236,41 +1216,6 @@ TEST_F(RtpSenderVideoTest, VideoLayersAllocationNotSentOnHigherTemporalLayers) { .HasExtension()); } -TEST_F(RtpSenderVideoTest, AbsoluteCaptureTime) { - constexpr int64_t kAbsoluteCaptureTimestampMs = 12345678; - uint8_t kFrame[kMaxPacketLength]; - rtp_module_->RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(), - kAbsoluteCaptureTimeExtensionId); - - RTPVideoHeader hdr; - hdr.frame_type = VideoFrameType::kVideoFrameKey; - rtp_sender_video_->SendVideo(kPayload, kType, kTimestamp, - kAbsoluteCaptureTimestampMs, kFrame, hdr, - kDefaultExpectedRetransmissionTimeMs, {}); - - absl::optional absolute_capture_time; - - // It is expected that one and only one of the packets sent on this video - // frame has absolute capture time header extension. - for (const RtpPacketReceived& packet : transport_.sent_packets()) { - if (absolute_capture_time.has_value()) { - EXPECT_FALSE(packet.HasExtension()); - } else { - absolute_capture_time = - packet.GetExtension(); - } - } - - // Verify the capture timestamp and that the clock offset is not set. - ASSERT_TRUE(absolute_capture_time.has_value()); - EXPECT_EQ( - absolute_capture_time->absolute_capture_timestamp, - Int64MsToUQ32x32(fake_clock_.ConvertTimestampToNtpTimeInMilliseconds( - kAbsoluteCaptureTimestampMs))); - EXPECT_FALSE( - absolute_capture_time->estimated_capture_clock_offset.has_value()); -} - TEST_F(RtpSenderVideoTest, AbsoluteCaptureTimeNotForwardedWhenImageHasNoCaptureTime) { uint8_t kFrame[kMaxPacketLength]; @@ -1289,10 +1234,7 @@ TEST_F(RtpSenderVideoTest, } } -// Essentially the same test as AbsoluteCaptureTime but with a field trial. -// After the field trial is experimented, we will remove AbsoluteCaptureTime. -TEST_F(RtpSenderVideoTest, AbsoluteCaptureTimeWithCaptureClockOffset) { - field_trials_.set_include_capture_clock_offset(true); +TEST_F(RtpSenderVideoTest, AbsoluteCaptureTime) { rtp_sender_video_ = std::make_unique( &fake_clock_, rtp_module_->RtpSender(), field_trials_); @@ -1499,7 +1441,7 @@ class RtpSenderVideoWithFrameTransformerTest : public ::testing::Test { protected: GlobalSimulatedTimeController time_controller_; - FieldTrialBasedConfig field_trials_; + test::ExplicitKeyValueConfig field_trials_{""}; LoopbackTransportTest transport_; RateLimiter retransmission_rate_limiter_; std::unique_ptr rtp_module_; diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension_unittest.cc index db077409ee5bc..e05df1a2667dd 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_layers_allocation_extension_unittest.cc @@ -13,7 +13,6 @@ #include "api/video/video_layers_allocation.h" #include "rtc_base/bit_buffer.h" #include "rtc_base/buffer.h" - #include "test/gmock.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc index b20877c7946a7..71e58eab24658 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc @@ -56,8 +56,6 @@ class TransformableVideoReceiverFrame return empty; } - const VideoFrameMetadata& GetMetadata() const override { return metadata_; } - VideoFrameMetadata Metadata() const override { return metadata_; } void SetMetadata(const VideoFrameMetadata&) override { @@ -121,13 +119,44 @@ void RtpVideoStreamReceiverFrameTransformerDelegate::OnTransformedFrame( void RtpVideoStreamReceiverFrameTransformerDelegate::ManageFrame( std::unique_ptr frame) { RTC_DCHECK_RUN_ON(&network_sequence_checker_); - RTC_CHECK_EQ(frame->GetDirection(), - TransformableFrameInterface::Direction::kReceiver); if (!receiver_) return; - auto transformed_frame = absl::WrapUnique( - static_cast(frame.release())); - receiver_->ManageFrame(std::move(*transformed_frame).ExtractFrame()); + if (frame->GetDirection() == + TransformableFrameInterface::Direction::kReceiver) { + auto transformed_frame = absl::WrapUnique( + static_cast(frame.release())); + receiver_->ManageFrame(std::move(*transformed_frame).ExtractFrame()); + } else { + RTC_CHECK_EQ(frame->GetDirection(), + TransformableFrameInterface::Direction::kSender); + // This frame is actually an frame encoded locally, to be sent, but has been + // fed back into this receiver's insertable stream writer. + // Create a reasonable RtpFrameObject as if this frame had been received + // over RTP, reusing the frameId as an analog for the RTP sequence number, + // and handle it as if it had been received. + // TODO(https://crbug.com/1250638): Rewrite the receiver's codepaths after + // this transform to be transport-agnostic and not need a faked rtp + // sequence number. + + auto transformed_frame = absl::WrapUnique( + static_cast(frame.release())); + VideoFrameMetadata metadata = transformed_frame->Metadata(); + RTPVideoHeader video_header = RTPVideoHeader::FromMetadata(metadata); + VideoSendTiming timing; + rtc::ArrayView data = transformed_frame->GetData(); + receiver_->ManageFrame(std::make_unique( + /*first_seq_num=*/metadata.GetFrameId().value_or(0), + /*last_seq_num=*/metadata.GetFrameId().value_or(0), + /*markerBit=*/video_header.is_last_frame_in_picture, + /*times_nacked=*/0, + /*first_packet_received_time=*/0, + /*last_packet_received_time=*/0, + /*rtp_timestamp=*/transformed_frame->GetTimestamp(), + /*ntp_time_ms=*/0, timing, transformed_frame->GetPayloadType(), + metadata.GetCodec(), metadata.GetRotation(), metadata.GetContentType(), + video_header, video_header.color_space, RtpPacketInfos(), + EncodedImageBuffer::Create(data.data(), data.size()))); + } } } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc index 707970e14fcb3..0fdc503e467db 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc +++ b/third_party/libwebrtc/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_transformable_video_frame.h" #include "api/units/timestamp.h" #include "call/video_receive_stream.h" #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h" @@ -31,6 +32,7 @@ namespace { using ::testing::_; using ::testing::ElementsAre; using ::testing::NiceMock; +using ::testing::Return; using ::testing::SaveArg; std::unique_ptr CreateRtpFrameObject( @@ -175,5 +177,43 @@ TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, delegate->TransformFrame(CreateRtpFrameObject(video_header, csrcs)); } +TEST(RtpVideoStreamReceiverFrameTransformerDelegateTest, + SenderFramesAreConvertedToReceiverFrames) { + rtc::AutoThread main_thread_; + TestRtpVideoFrameReceiver receiver; + auto mock_frame_transformer = + rtc::make_ref_counted>(); + auto delegate = + rtc::make_ref_counted( + &receiver, mock_frame_transformer, rtc::Thread::Current(), + /*remote_ssrc*/ 1111); + + auto mock_sender_frame = + std::make_unique>(); + ON_CALL(*mock_sender_frame, GetDirection) + .WillByDefault(Return(TransformableFrameInterface::Direction::kSender)); + VideoFrameMetadata metadata; + metadata.SetCodec(kVideoCodecVP8); + metadata.SetRTPVideoHeaderCodecSpecifics(RTPVideoHeaderVP8()); + ON_CALL(*mock_sender_frame, Metadata).WillByDefault(Return(metadata)); + rtc::scoped_refptr buffer = + EncodedImageBuffer::Create(1); + ON_CALL(*mock_sender_frame, GetData) + .WillByDefault(Return(rtc::ArrayView(*buffer))); + + rtc::scoped_refptr callback; + EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameSinkCallback) + .WillOnce(SaveArg<0>(&callback)); + delegate->Init(); + ASSERT_TRUE(callback); + + EXPECT_CALL(receiver, ManageFrame) + .WillOnce([&](std::unique_ptr frame) { + EXPECT_EQ(frame->codec_type(), metadata.GetCodec()); + }); + callback->OnTransformedFrame(std::move(mock_sender_frame)); + rtc::ThreadManager::ProcessAllMessageQueuesForTesting(); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.cc index 65f21700d0160..46a46ef51d6a1 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.cc @@ -17,27 +17,38 @@ namespace webrtc { -constexpr int64_t SourceTracker::kTimeoutMs; - -SourceTracker::SourceTracker(Clock* clock) : clock_(clock) {} +SourceTracker::SourceTracker(Clock* clock) + : worker_thread_(TaskQueueBase::Current()), clock_(clock) { + RTC_DCHECK(worker_thread_); + RTC_DCHECK(clock_); +} -void SourceTracker::OnFrameDelivered(const RtpPacketInfos& packet_infos) { +void SourceTracker::OnFrameDelivered(RtpPacketInfos packet_infos) { if (packet_infos.empty()) { return; } - TRACE_EVENT0("webrtc", "SourceTracker::OnFrameDelivered"); + Timestamp now = clock_->CurrentTime(); + worker_thread_->PostTask( + SafeTask(worker_safety_.flag(), + [this, packet_infos = std::move(packet_infos), now]() { + RTC_DCHECK_RUN_ON(worker_thread_); + OnFrameDeliveredInternal(now, packet_infos); + })); +} - int64_t now_ms = clock_->TimeInMilliseconds(); - MutexLock lock_scope(&lock_); +void SourceTracker::OnFrameDeliveredInternal( + Timestamp now, + const RtpPacketInfos& packet_infos) { + TRACE_EVENT0("webrtc", "SourceTracker::OnFrameDelivered"); for (const RtpPacketInfo& packet_info : packet_infos) { for (uint32_t csrc : packet_info.csrcs()) { SourceKey key(RtpSourceType::CSRC, csrc); SourceEntry& entry = UpdateEntry(key); - const auto packet_time = packet_info.receive_time().ms(); - entry.timestamp_ms = packet_time ? packet_time : now_ms; + const auto packet_time = packet_info.receive_time(); + entry.timestamp = packet_time.ms() ? packet_time : now; entry.audio_level = packet_info.audio_level(); entry.absolute_capture_time = packet_info.absolute_capture_time(); entry.local_capture_clock_offset = @@ -48,30 +59,28 @@ void SourceTracker::OnFrameDelivered(const RtpPacketInfos& packet_infos) { SourceKey key(RtpSourceType::SSRC, packet_info.ssrc()); SourceEntry& entry = UpdateEntry(key); - entry.timestamp_ms = now_ms; + entry.timestamp = now; entry.audio_level = packet_info.audio_level(); entry.absolute_capture_time = packet_info.absolute_capture_time(); entry.local_capture_clock_offset = packet_info.local_capture_clock_offset(); entry.rtp_timestamp = packet_info.rtp_timestamp(); } - PruneEntries(now_ms); + PruneEntries(now); } std::vector SourceTracker::GetSources() const { - std::vector sources; - - int64_t now_ms = clock_->TimeInMilliseconds(); - MutexLock lock_scope(&lock_); + RTC_DCHECK_RUN_ON(worker_thread_); - PruneEntries(now_ms); + PruneEntries(clock_->CurrentTime()); + std::vector sources; for (const auto& pair : list_) { const SourceKey& key = pair.first; const SourceEntry& entry = pair.second; sources.emplace_back( - entry.timestamp_ms, key.source, key.source_type, entry.rtp_timestamp, + entry.timestamp.ms(), key.source, key.source_type, entry.rtp_timestamp, RtpSource::Extensions{ .audio_level = entry.audio_level, .absolute_capture_time = entry.absolute_capture_time, @@ -102,10 +111,9 @@ SourceTracker::SourceEntry& SourceTracker::UpdateEntry(const SourceKey& key) { return list_.front().second; } -void SourceTracker::PruneEntries(int64_t now_ms) const { - int64_t prune_ms = now_ms - kTimeoutMs; - - while (!list_.empty() && list_.back().second.timestamp_ms < prune_ms) { +void SourceTracker::PruneEntries(Timestamp now) const { + Timestamp prune = now - kTimeout; + while (!list_.empty() && list_.back().second.timestamp < prune) { map_.erase(list_.back().first); list_.pop_back(); } diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.h b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.h index f9e8354d44e03..30a5b8a4fa958 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.h +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker.h @@ -19,9 +19,11 @@ #include "absl/types/optional.h" #include "api/rtp_packet_infos.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" #include "api/transport/rtp/rtp_source.h" #include "api/units/time_delta.h" -#include "rtc_base/synchronization/mutex.h" +#include "api/units/timestamp.h" #include "rtc_base/time_utils.h" #include "system_wrappers/include/clock.h" @@ -36,7 +38,7 @@ class SourceTracker { public: // Amount of time before the entry associated with an update is removed. See: // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources - static constexpr int64_t kTimeoutMs = 10000; // 10 seconds + static constexpr TimeDelta kTimeout = TimeDelta::Seconds(10); explicit SourceTracker(Clock* clock); @@ -47,7 +49,7 @@ class SourceTracker { // Updates the source entries when a frame is delivered to the // RTCRtpReceiver's MediaStreamTrack. - void OnFrameDelivered(const RtpPacketInfos& packet_infos); + void OnFrameDelivered(RtpPacketInfos packet_infos); // Returns an `RtpSource` for each unique SSRC and CSRC identifier updated in // the last `kTimeoutMs` milliseconds. Entries appear in reverse chronological @@ -83,11 +85,11 @@ class SourceTracker { // Timestamp indicating the most recent time a frame from an RTP packet, // originating from this source, was delivered to the RTCRtpReceiver's // MediaStreamTrack. Its reference clock is the outer class's `clock_`. - int64_t timestamp_ms; + Timestamp timestamp = Timestamp::MinusInfinity(); // Audio level from an RFC 6464 or RFC 6465 header extension received with // the most recent packet used to assemble the frame associated with - // `timestamp_ms`. May be absent. Only relevant for audio receivers. See the + // `timestamp`. May be absent. Only relevant for audio receivers. See the // specs for `RTCRtpContributingSource` for more info. absl::optional audio_level; @@ -104,8 +106,8 @@ class SourceTracker { absl::optional local_capture_clock_offset; // RTP timestamp of the most recent packet used to assemble the frame - // associated with `timestamp_ms`. - uint32_t rtp_timestamp; + // associated with `timestamp`. + uint32_t rtp_timestamp = 0; }; using SourceList = std::list>; @@ -114,23 +116,27 @@ class SourceTracker { SourceKeyHasher, SourceKeyComparator>; + void OnFrameDeliveredInternal(Timestamp now, + const RtpPacketInfos& packet_infos) + RTC_RUN_ON(worker_thread_); + // Updates an entry by creating it (if it didn't previously exist) and moving // it to the front of the list. Returns a reference to the entry. - SourceEntry& UpdateEntry(const SourceKey& key) - RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); + SourceEntry& UpdateEntry(const SourceKey& key) RTC_RUN_ON(worker_thread_); // Removes entries that have timed out. Marked as "const" so that we can do // pruning in getters. - void PruneEntries(int64_t now_ms) const RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_); + void PruneEntries(Timestamp now) const RTC_RUN_ON(worker_thread_); + TaskQueueBase* const worker_thread_; Clock* const clock_; - mutable Mutex lock_; // Entries are stored in reverse chronological order (i.e. with the most // recently updated entries appearing first). Mutability is needed for timeout // pruning in const functions. - mutable SourceList list_ RTC_GUARDED_BY(lock_); - mutable SourceMap map_ RTC_GUARDED_BY(lock_); + mutable SourceList list_ RTC_GUARDED_BY(worker_thread_); + mutable SourceMap map_ RTC_GUARDED_BY(worker_thread_); + ScopedTaskSafety worker_safety_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker_unittest.cc index b3e3102d7e954..c11142bcb4ec6 100644 --- a/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker_unittest.cc +++ b/third_party/libwebrtc/modules/rtp_rtcp/source/source_tracker_unittest.cc @@ -25,6 +25,7 @@ #include "system_wrappers/include/ntp_time.h" #include "test/gmock.h" #include "test/gtest.h" +#include "test/time_controller/simulated_time_controller.h" namespace webrtc { namespace { @@ -121,29 +122,29 @@ class SourceTrackerRandomTest return RtpPacketInfos(std::move(packet_infos)); } - int64_t GenerateClockAdvanceTimeMilliseconds() { + TimeDelta GenerateClockAdvanceTime() { double roll = std::uniform_real_distribution(0.0, 1.0)(generator_); if (roll < 0.05) { - return 0; + return TimeDelta::Zero(); } if (roll < 0.08) { - return SourceTracker::kTimeoutMs - 1; + return SourceTracker::kTimeout - TimeDelta::Millis(1); } if (roll < 0.11) { - return SourceTracker::kTimeoutMs; + return SourceTracker::kTimeout; } if (roll < 0.19) { - return std::uniform_int_distribution( - SourceTracker::kTimeoutMs, - SourceTracker::kTimeoutMs * 1000)(generator_); + return TimeDelta::Millis(std::uniform_int_distribution( + SourceTracker::kTimeout.ms(), + SourceTracker::kTimeout.ms() * 1000)(generator_)); } - return std::uniform_int_distribution( - 1, SourceTracker::kTimeoutMs - 1)(generator_); + return TimeDelta::Millis(std::uniform_int_distribution( + 1, SourceTracker::kTimeout.ms() - 1)(generator_)); } private: @@ -209,6 +210,10 @@ class SourceTrackerRandomTest std::uniform_int_distribution()(generator_)); } + protected: + GlobalSimulatedTimeController time_controller_{Timestamp::Seconds(1000)}; + + private: const uint32_t ssrcs_count_; const uint32_t csrcs_count_; @@ -220,9 +225,8 @@ class SourceTrackerRandomTest TEST_P(SourceTrackerRandomTest, RandomOperations) { constexpr size_t kIterationsCount = 200; - SimulatedClock clock(1000000000000ULL); - SourceTracker actual_tracker(&clock); - ExpectedSourceTracker expected_tracker(&clock); + SourceTracker actual_tracker(time_controller_.GetClock()); + ExpectedSourceTracker expected_tracker(time_controller_.GetClock()); ASSERT_THAT(actual_tracker.GetSources(), IsEmpty()); ASSERT_THAT(expected_tracker.GetSources(), IsEmpty()); @@ -233,8 +237,7 @@ TEST_P(SourceTrackerRandomTest, RandomOperations) { actual_tracker.OnFrameDelivered(packet_infos); expected_tracker.OnFrameDelivered(packet_infos); - clock.AdvanceTimeMilliseconds(GenerateClockAdvanceTimeMilliseconds()); - + time_controller_.AdvanceTime(GenerateClockAdvanceTime()); ASSERT_THAT(actual_tracker.GetSources(), ElementsAreArray(expected_tracker.GetSources())); } @@ -246,8 +249,8 @@ INSTANTIATE_TEST_SUITE_P(All, /*csrcs_count_=*/Values(0, 1, 3, 7))); TEST(SourceTrackerTest, StartEmpty) { - SimulatedClock clock(1000000000000ULL); - SourceTracker tracker(&clock); + GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); + SourceTracker tracker(time_controller.GetClock()); EXPECT_THAT(tracker.GetSources(), IsEmpty()); } @@ -269,8 +272,8 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesDistinctSsrcs) { constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70); - SimulatedClock clock(1000000000000ULL); - SourceTracker tracker(&clock); + GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); + SourceTracker tracker(time_controller.GetClock()); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) @@ -282,7 +285,7 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesDistinctSsrcs) { .set_absolute_capture_time(kAbsoluteCaptureTime) .set_local_capture_clock_offset(kLocalCaptureClockOffset)})); - int64_t timestamp_ms = clock.TimeInMilliseconds(); + Timestamp timestamp = time_controller.GetClock()->CurrentTime(); constexpr RtpSource::Extensions extensions0 = { .audio_level = kAudioLevel0, .absolute_capture_time = kAbsoluteCaptureTime, @@ -292,17 +295,20 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesDistinctSsrcs) { .absolute_capture_time = kAbsoluteCaptureTime, .local_capture_clock_offset = kLocalCaptureClockOffset}; - EXPECT_THAT(tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms, kSsrc2, RtpSourceType::SSRC, - kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms, kCsrcs2, RtpSourceType::CSRC, - kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms, kSsrc1, RtpSourceType::SSRC, - kRtpTimestamp0, extensions0), - RtpSource(timestamp_ms, kCsrcs1, RtpSourceType::CSRC, - kRtpTimestamp0, extensions0), - RtpSource(timestamp_ms, kCsrcs0, RtpSourceType::CSRC, - kRtpTimestamp0, extensions0))); + time_controller.AdvanceTime(TimeDelta::Zero()); + + EXPECT_THAT( + tracker.GetSources(), + ElementsAre(RtpSource(timestamp.ms(), kSsrc2, RtpSourceType::SSRC, + kRtpTimestamp1, extensions1), + RtpSource(timestamp.ms(), kCsrcs2, RtpSourceType::CSRC, + kRtpTimestamp1, extensions1), + RtpSource(timestamp.ms(), kSsrc1, RtpSourceType::SSRC, + kRtpTimestamp0, extensions0), + RtpSource(timestamp.ms(), kCsrcs1, RtpSourceType::CSRC, + kRtpTimestamp0, extensions0), + RtpSource(timestamp.ms(), kCsrcs0, RtpSourceType::CSRC, + kRtpTimestamp0, extensions0))); } TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesSameSsrc) { @@ -324,8 +330,8 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesSameSsrc) { constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70); constexpr Timestamp kReceiveTime2 = Timestamp::Millis(80); - SimulatedClock clock(1000000000000ULL); - SourceTracker tracker(&clock); + GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); + SourceTracker tracker(time_controller.GetClock()); tracker.OnFrameDelivered(RtpPacketInfos({ RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) @@ -342,7 +348,8 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesSameSsrc) { .set_local_capture_clock_offset(kLocalCaptureClockOffset), })); - int64_t timestamp_ms = clock.TimeInMilliseconds(); + time_controller.AdvanceTime(TimeDelta::Zero()); + Timestamp timestamp = time_controller.GetClock()->CurrentTime(); constexpr RtpSource::Extensions extensions0 = { .audio_level = kAudioLevel0, .absolute_capture_time = kAbsoluteCaptureTime, @@ -356,15 +363,16 @@ TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesSameSsrc) { .absolute_capture_time = kAbsoluteCaptureTime, .local_capture_clock_offset = kLocalCaptureClockOffset}; - EXPECT_THAT(tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms, kSsrc, RtpSourceType::SSRC, - kRtpTimestamp2, extensions2), - RtpSource(timestamp_ms, kCsrcs0, RtpSourceType::CSRC, - kRtpTimestamp2, extensions2), - RtpSource(timestamp_ms, kCsrcs2, RtpSourceType::CSRC, - kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms, kCsrcs1, RtpSourceType::CSRC, - kRtpTimestamp0, extensions0))); + EXPECT_THAT( + tracker.GetSources(), + ElementsAre(RtpSource(timestamp.ms(), kSsrc, RtpSourceType::SSRC, + kRtpTimestamp2, extensions2), + RtpSource(timestamp.ms(), kCsrcs0, RtpSourceType::CSRC, + kRtpTimestamp2, extensions2), + RtpSource(timestamp.ms(), kCsrcs2, RtpSourceType::CSRC, + kRtpTimestamp1, extensions1), + RtpSource(timestamp.ms(), kCsrcs1, RtpSourceType::CSRC, + kRtpTimestamp0, extensions0))); } TEST(SourceTrackerTest, OnFrameDeliveredUpdatesSources) { @@ -408,8 +416,8 @@ TEST(SourceTrackerTest, OnFrameDeliveredUpdatesSources) { .absolute_capture_time = kAbsoluteCaptureTime2, .local_capture_clock_offset = kLocalCaptureClockOffset2}; - SimulatedClock clock(1000000000000ULL); - SourceTracker tracker(&clock); + GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); + SourceTracker tracker(time_controller.GetClock()); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) @@ -417,40 +425,42 @@ TEST(SourceTrackerTest, OnFrameDeliveredUpdatesSources) { .set_absolute_capture_time(kAbsoluteCaptureTime0) .set_local_capture_clock_offset(kLocalCaptureClockOffset0)})); - int64_t timestamp_ms_0 = clock.TimeInMilliseconds(); + time_controller.AdvanceTime(TimeDelta::Zero()); + Timestamp timestamp_0 = time_controller.GetClock()->CurrentTime(); EXPECT_THAT( tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms_0, kSsrc1, RtpSourceType::SSRC, + ElementsAre(RtpSource(timestamp_0.ms(), kSsrc1, RtpSourceType::SSRC, kRtpTimestamp0, extensions0), - RtpSource(timestamp_ms_0, kCsrcs1, RtpSourceType::CSRC, + RtpSource(timestamp_0.ms(), kCsrcs1, RtpSourceType::CSRC, kRtpTimestamp0, extensions0), - RtpSource(timestamp_ms_0, kCsrcs0, RtpSourceType::CSRC, + RtpSource(timestamp_0.ms(), kCsrcs0, RtpSourceType::CSRC, kRtpTimestamp0, extensions0))); // Deliver packets with updated sources. - clock.AdvanceTimeMilliseconds(17); + time_controller.AdvanceTime(TimeDelta::Millis(17)); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kReceiveTime1) .set_audio_level(kAudioLevel1) .set_absolute_capture_time(kAbsoluteCaptureTime1) .set_local_capture_clock_offset(kLocalCaptureClockOffset1)})); - int64_t timestamp_ms_1 = clock.TimeInMilliseconds(); + time_controller.AdvanceTime(TimeDelta::Zero()); + Timestamp timestamp_1 = time_controller.GetClock()->CurrentTime(); EXPECT_THAT( tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms_1, kSsrc1, RtpSourceType::SSRC, + ElementsAre(RtpSource(timestamp_1.ms(), kSsrc1, RtpSourceType::SSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_1, kCsrcs2, RtpSourceType::CSRC, + RtpSource(timestamp_1.ms(), kCsrcs2, RtpSourceType::CSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_1, kCsrcs0, RtpSourceType::CSRC, + RtpSource(timestamp_1.ms(), kCsrcs0, RtpSourceType::CSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_0, kCsrcs1, RtpSourceType::CSRC, + RtpSource(timestamp_0.ms(), kCsrcs1, RtpSourceType::CSRC, kRtpTimestamp0, extensions0))); // Deliver more packets with update csrcs and a new ssrc. - clock.AdvanceTimeMilliseconds(17); + time_controller.AdvanceTime(TimeDelta::Millis(17)); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc2, {kCsrcs0}, kRtpTimestamp2, kReceiveTime2) @@ -458,19 +468,20 @@ TEST(SourceTrackerTest, OnFrameDeliveredUpdatesSources) { .set_absolute_capture_time(kAbsoluteCaptureTime2) .set_local_capture_clock_offset(kLocalCaptureClockOffset2)})); - int64_t timestamp_ms_2 = clock.TimeInMilliseconds(); + time_controller.AdvanceTime(TimeDelta::Zero()); + Timestamp timestamp_2 = time_controller.GetClock()->CurrentTime(); EXPECT_THAT( tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms_2, kSsrc2, RtpSourceType::SSRC, + ElementsAre(RtpSource(timestamp_2.ms(), kSsrc2, RtpSourceType::SSRC, kRtpTimestamp2, extensions2), - RtpSource(timestamp_ms_2, kCsrcs0, RtpSourceType::CSRC, + RtpSource(timestamp_2.ms(), kCsrcs0, RtpSourceType::CSRC, kRtpTimestamp2, extensions2), - RtpSource(timestamp_ms_1, kSsrc1, RtpSourceType::SSRC, + RtpSource(timestamp_1.ms(), kSsrc1, RtpSourceType::SSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_1, kCsrcs2, RtpSourceType::CSRC, + RtpSource(timestamp_1.ms(), kCsrcs2, RtpSourceType::CSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_0, kCsrcs1, RtpSourceType::CSRC, + RtpSource(timestamp_0.ms(), kCsrcs1, RtpSourceType::CSRC, kRtpTimestamp0, extensions0))); } @@ -494,8 +505,8 @@ TEST(SourceTrackerTest, TimedOutSourcesAreRemoved) { constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61); - SimulatedClock clock(1000000000000ULL); - SourceTracker tracker(&clock); + GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); + SourceTracker tracker(time_controller.GetClock()); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) @@ -503,7 +514,7 @@ TEST(SourceTrackerTest, TimedOutSourcesAreRemoved) { .set_absolute_capture_time(kAbsoluteCaptureTime0) .set_local_capture_clock_offset(kLocalCaptureClockOffset0)})); - clock.AdvanceTimeMilliseconds(17); + time_controller.AdvanceTime(TimeDelta::Millis(17)); tracker.OnFrameDelivered(RtpPacketInfos( {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kReceiveTime1) @@ -511,9 +522,9 @@ TEST(SourceTrackerTest, TimedOutSourcesAreRemoved) { .set_absolute_capture_time(kAbsoluteCaptureTime1) .set_local_capture_clock_offset(kLocalCaptureClockOffset1)})); - int64_t timestamp_ms_1 = clock.TimeInMilliseconds(); + Timestamp timestamp_1 = time_controller.GetClock()->CurrentTime(); - clock.AdvanceTimeMilliseconds(SourceTracker::kTimeoutMs); + time_controller.AdvanceTime(SourceTracker::kTimeout); constexpr RtpSource::Extensions extensions1 = { .audio_level = kAudioLevel1, @@ -522,11 +533,11 @@ TEST(SourceTrackerTest, TimedOutSourcesAreRemoved) { EXPECT_THAT( tracker.GetSources(), - ElementsAre(RtpSource(timestamp_ms_1, kSsrc, RtpSourceType::SSRC, + ElementsAre(RtpSource(timestamp_1.ms(), kSsrc, RtpSourceType::SSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_1, kCsrcs2, RtpSourceType::CSRC, + RtpSource(timestamp_1.ms(), kCsrcs2, RtpSourceType::CSRC, kRtpTimestamp1, extensions1), - RtpSource(timestamp_ms_1, kCsrcs0, RtpSourceType::CSRC, + RtpSource(timestamp_1.ms(), kCsrcs0, RtpSourceType::CSRC, kRtpTimestamp1, extensions1))); } diff --git a/third_party/libwebrtc/modules/third_party/g711/g711.h b/third_party/libwebrtc/modules/third_party/g711/g711.h index 4eef42c0bf148..4af819a0af6b2 100644 --- a/third_party/libwebrtc/modules/third_party/g711/g711.h +++ b/third_party/libwebrtc/modules/third_party/g711/g711.h @@ -201,7 +201,7 @@ static __inline int bottom_bit(unsigned int bits) { * John Wiley & Sons, pps 98-111 and 472-476. */ -//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD +// #define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD //*/ #define ULAW_BIAS 0x84 /* Bias for linear code. */ diff --git a/third_party/libwebrtc/modules/utility/BUILD.gn b/third_party/libwebrtc/modules/utility/BUILD.gn index 46bca17f02da6..b8d75865f7685 100644 --- a/third_party/libwebrtc/modules/utility/BUILD.gn +++ b/third_party/libwebrtc/modules/utility/BUILD.gn @@ -9,38 +9,16 @@ import("../../webrtc.gni") rtc_source_set("utility") { - sources = [ - "maybe_worker_thread.cc", - "maybe_worker_thread.h", - ] - - deps = [ - "../../api:field_trials_view", - "../../api:sequence_checker", - "../../api/task_queue", - "../../api/task_queue:pending_task_safety_flag", - "../../rtc_base:checks", - "../../rtc_base:logging", - "../../rtc_base:macromagic", - "../../rtc_base:rtc_event", - "../../rtc_base:rtc_task_queue", - ] - - absl_deps = [ - "//third_party/abseil-cpp/absl/functional:any_invocable", - "//third_party/abseil-cpp/absl/strings:strings", - ] - if (is_android) { visibility = [ "*" ] - sources += [ + sources = [ "include/helpers_android.h", "include/jvm_android.h", "source/helpers_android.cc", "source/jvm_android.cc", ] - deps += [ + deps = [ "../../api:sequence_checker", "../../rtc_base:checks", "../../rtc_base:logging", @@ -53,26 +31,3 @@ rtc_source_set("utility") { } } } - -if (rtc_include_tests) { - rtc_library("utility_unittests") { - testonly = true - - sources = [ "maybe_worker_thread_unittests.cc" ] - deps = [ - ":utility", - "../../api:sequence_checker", - "../../api/task_queue", - "../../api/task_queue:default_task_queue_factory", - "../../api/task_queue:pending_task_safety_flag", - "../../api/units:time_delta", - "../../rtc_base:rtc_event", - "../../rtc_base:threading", - "../../test:explicit_key_value_config", - "../../test:field_trial", - "../../test:test_main", - "../../test:test_support", - "../../test/time_controller", - ] - } -} diff --git a/third_party/libwebrtc/modules/utility/maybe_worker_thread.cc b/third_party/libwebrtc/modules/utility/maybe_worker_thread.cc deleted file mode 100644 index aaa79bb9f3bb9..0000000000000 --- a/third_party/libwebrtc/modules/utility/maybe_worker_thread.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include "modules/utility/maybe_worker_thread.h" - -#include - -#include "api/task_queue/pending_task_safety_flag.h" -#include "api/task_queue/task_queue_base.h" -#include "rtc_base/checks.h" -#include "rtc_base/event.h" -#include "rtc_base/logging.h" -#include "rtc_base/task_queue.h" - -namespace webrtc { - -MaybeWorkerThread::MaybeWorkerThread(const FieldTrialsView& field_trials, - absl::string_view task_queue_name, - TaskQueueFactory* factory) - : owned_task_queue_( - !field_trials.IsDisabled("WebRTC-SendPacketsOnWorkerThread") - ? nullptr - : factory->CreateTaskQueue(task_queue_name, - rtc::TaskQueue::Priority::NORMAL)), - worker_thread_(TaskQueueBase::Current()) { - RTC_DCHECK(worker_thread_); - RTC_LOG(LS_INFO) << "WebRTC-SendPacketsOnWorkerThread" - << (owned_task_queue_ ? " Disabled" : " Enabled"); -} - -MaybeWorkerThread::~MaybeWorkerThread() { - RTC_DCHECK_RUN_ON(&sequence_checker_); - - if (owned_task_queue_) { - // owned_task_queue_ must be a valid pointer when the task queue is - // destroyed since there may be tasks that use this object that run when the - // task queue is deleted. - owned_task_queue_->Delete(); - owned_task_queue_.release(); - } -} - -void MaybeWorkerThread::RunSynchronous(absl::AnyInvocable task) { - if (owned_task_queue_) { - rtc::Event thread_sync_event; - auto closure = [&thread_sync_event, task = std::move(task)]() mutable { - std::move(task)(); - thread_sync_event.Set(); - }; - owned_task_queue_->PostTask(std::move(closure)); - thread_sync_event.Wait(rtc::Event::kForever); - } else { - RTC_DCHECK_RUN_ON(&sequence_checker_); - std::move(task)(); - } -} - -void MaybeWorkerThread::RunOrPost(absl::AnyInvocable task) { - if (owned_task_queue_) { - owned_task_queue_->PostTask(std::move(task)); - } else { - RTC_DCHECK_RUN_ON(&sequence_checker_); - std::move(task)(); - } -} - -TaskQueueBase* MaybeWorkerThread::TaskQueueForDelayedTasks() const { - RTC_DCHECK(IsCurrent()); - return owned_task_queue_ ? owned_task_queue_.get() : worker_thread_; -} - -TaskQueueBase* MaybeWorkerThread::TaskQueueForPost() const { - return owned_task_queue_ ? owned_task_queue_.get() : worker_thread_; -} - -bool MaybeWorkerThread::IsCurrent() const { - if (owned_task_queue_) { - return owned_task_queue_->IsCurrent(); - } - return worker_thread_->IsCurrent(); -} - -absl::AnyInvocable MaybeWorkerThread::MaybeSafeTask( - rtc::scoped_refptr flag, - absl::AnyInvocable task) { - if (owned_task_queue_) { - return task; - } else { - return SafeTask(std::move(flag), std::move(task)); - } -} - -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/utility/maybe_worker_thread.h b/third_party/libwebrtc/modules/utility/maybe_worker_thread.h deleted file mode 100644 index a93a173bf689d..0000000000000 --- a/third_party/libwebrtc/modules/utility/maybe_worker_thread.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#ifndef MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ -#define MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ - -#include - -#include "absl/strings/string_view.h" -#include "api/field_trials_view.h" -#include "api/sequence_checker.h" -#include "api/task_queue/pending_task_safety_flag.h" -#include "api/task_queue/task_queue_base.h" -#include "api/task_queue/task_queue_factory.h" -#include "rtc_base/thread_annotations.h" - -namespace webrtc { - -// Helper class used by experiment to replace usage of the -// RTP worker task queue owned by RtpTransportControllerSend, and the pacer task -// queue owned by TaskQueuePacedSender with the one and only worker thread. -// Tasks will run on the target sequence which is either the worker thread or -// one of these task queues depending on the field trial -// "WebRTC-SendPacketsOnWorkerThread". -// This class is assumed to be created on the worker thread and the worker -// thread is assumed to outlive an instance of this class. -// -// Experiment can be tracked in -// https://bugs.chromium.org/p/webrtc/issues/detail?id=14502 -// -// After experiment evaluation, this class should be deleted. -// Calls to RunOrPost and RunSynchronous should be removed and the task should -// be invoked immediately. -// Instead of MaybeSafeTask a SafeTask should be used when posting tasks. -class RTC_LOCKABLE MaybeWorkerThread { - public: - MaybeWorkerThread(const FieldTrialsView& field_trials, - absl::string_view task_queue_name, - TaskQueueFactory* factory); - ~MaybeWorkerThread(); - - // Runs `task` immediately on the worker thread if in experiment, otherwise - // post the task on the task queue. - void RunOrPost(absl::AnyInvocable task); - // Runs `task` immediately on the worker thread if in experiment, otherwise - // post the task on the task queue and use an even to wait for completion. - void RunSynchronous(absl::AnyInvocable task); - - // Used for posting delayed or repeated tasks on the worker thread or task - // queue depending on the field trial. DCHECKs that this method is called on - // the target sequence. - TaskQueueBase* TaskQueueForDelayedTasks() const; - - // Used when a task has to be posted from one sequence to the target - // sequence. A task should only be posted if a sequence hop is needed. - TaskQueueBase* TaskQueueForPost() const; - - // Workaround to use a SafeTask only if the target sequence is the worker - // thread. This is used when a SafeTask can not be used because the object - // that posted the task is not destroyed on the target sequence. Instead, the - // caller has to guarantee that this MaybeWorkerThread is destroyed first - // since that guarantee that the posted task is deleted or run before the - // owning class. - absl::AnyInvocable MaybeSafeTask( - rtc::scoped_refptr flag, - absl::AnyInvocable task); - - // To implement macro RTC_DCHECK_RUN_ON. - // Implementation delegate to the actual used sequence. - bool IsCurrent() const; - - private: - SequenceChecker sequence_checker_; - std::unique_ptr owned_task_queue_; - TaskQueueBase* const worker_thread_; -}; - -} // namespace webrtc - -#endif // MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ diff --git a/third_party/libwebrtc/modules/utility/maybe_worker_thread_unittests.cc b/third_party/libwebrtc/modules/utility/maybe_worker_thread_unittests.cc deleted file mode 100644 index 2ce4d19727504..0000000000000 --- a/third_party/libwebrtc/modules/utility/maybe_worker_thread_unittests.cc +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ -#include - -#include "api/sequence_checker.h" -#include "api/task_queue/pending_task_safety_flag.h" -#include "api/task_queue/task_queue_factory.h" -#include "api/units/time_delta.h" -#include "modules/utility/maybe_worker_thread.h" -#include "rtc_base/event.h" -#include "test/explicit_key_value_config.h" -#include "test/gtest.h" -#include "test/time_controller/real_time_controller.h" - -namespace webrtc { - -namespace { - -constexpr char kFieldTrialEnabledString[] = - "WebRTC-SendPacketsOnWorkerThread/Enabled/"; -constexpr char kFieldTrialDisabledString[] = - "WebRTC-SendPacketsOnWorkerThread/Disabled/"; - -TEST(MaybeWorkerThreadTest, RunOrPostRunOnWorkerThreadInExperiment) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - SequenceChecker checker; - bool run = false; - m.RunOrPost([&] { - EXPECT_TRUE(checker.IsCurrent()); - run = true; - }); - EXPECT_TRUE(run); -} - -TEST(MaybeWorkerThreadTest, RunOrPostPostsOnTqPerDefault) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - SequenceChecker checker; - rtc::Event event; - m.RunOrPost([&] { - EXPECT_FALSE(checker.IsCurrent()); - event.Set(); - }); - EXPECT_TRUE(event.Wait(TimeDelta::Seconds(10))); -} - -TEST(MaybeWorkerThreadTest, RunSynchronousRunOnWorkerThreadInExperiment) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - SequenceChecker checker; - bool run = false; - m.RunSynchronous([&] { - EXPECT_TRUE(checker.IsCurrent()); - run = true; - }); - EXPECT_TRUE(run); -} - -TEST(MaybeWorkerThreadTest, RunSynchronousRunOnTqPerDefault) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - SequenceChecker checker; - bool run = false; - m.RunSynchronous([&] { - EXPECT_FALSE(checker.IsCurrent()); - run = true; - }); - EXPECT_TRUE(run); -} - -TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskPerDefault) { - // We cant really test that the return value from MaybeSafeTask is a SafeTask. - // But we can test that the safety flag does not have more references after a - // call. - test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - rtc::scoped_refptr flag = - PendingTaskSafetyFlag::Create(); - auto closure = m.MaybeSafeTask(flag, [] {}); - EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kDroppedLastRef); - flag.release(); -} - -TEST(MaybeWorkerThreadTest, MaybeSafeTaskDoesNotReturnSafeTaskInExperiment) { - // We cant really test that the return value from MaybeSafeTask is a SafeTask. - // But we can test that the safety flag does have one more references after a - // call. - test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - rtc::scoped_refptr flag = - PendingTaskSafetyFlag::Create(); - auto closure = m.MaybeSafeTask(flag, [] {}); - EXPECT_EQ(flag->Release(), rtc::RefCountReleaseStatus::kOtherRefsRemained); - flag.release(); -} - -TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectPerDefault) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - EXPECT_FALSE(m.IsCurrent()); - m.RunSynchronous([&] { EXPECT_TRUE(m.IsCurrent()); }); -} - -TEST(MaybeWorkerThreadTest, IsCurrentBehavesCorrectInExperiment) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); - RealTimeController controller; - MaybeWorkerThread m(field_trial, "test_tq", controller.GetTaskQueueFactory()); - - EXPECT_TRUE(m.IsCurrent()); - auto tq = controller.GetTaskQueueFactory()->CreateTaskQueue( - "tq", TaskQueueFactory::Priority::NORMAL); - rtc::Event event; - tq->PostTask([&] { - EXPECT_FALSE(m.IsCurrent()); - event.Set(); - }); - ASSERT_TRUE(event.Wait(TimeDelta::Seconds(10))); -} - -TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorPerDefault) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialDisabledString); - RealTimeController controller; - { - MaybeWorkerThread m(field_trial, "test_tq", - controller.GetTaskQueueFactory()); - m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); }); - } -} - -TEST(MaybeWorkerThreadTest, IsCurrentCanBeCalledInDestructorInExperiment) { - test::ExplicitKeyValueConfig field_trial(kFieldTrialEnabledString); - RealTimeController controller; - { - MaybeWorkerThread m(field_trial, "test_tq", - controller.GetTaskQueueFactory()); - m.RunOrPost([&] { EXPECT_TRUE(m.IsCurrent()); }); - } -} - -} // namespace -} // namespace webrtc diff --git a/third_party/libwebrtc/modules/utility/utility_gn/moz.build b/third_party/libwebrtc/modules/utility/utility_gn/moz.build index b932f5da73dab..8e60046c3417d 100644 --- a/third_party/libwebrtc/modules/utility/utility_gn/moz.build +++ b/third_party/libwebrtc/modules/utility/utility_gn/moz.build @@ -30,10 +30,6 @@ LOCAL_INCLUDES += [ "/tools/profiler/public" ] -UNIFIED_SOURCES += [ - "/third_party/libwebrtc/modules/utility/maybe_worker_thread.cc" -] - if not CONFIG["MOZ_DEBUG"]: DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0" @@ -128,10 +124,6 @@ if CONFIG["OS_TARGET"] == "WINNT": DEFINES["_WINDOWS"] = True DEFINES["__STD_C"] = True - OS_LIBS += [ - "winmm" - ] - if CONFIG["CPU_ARCH"] == "aarch64": DEFINES["WEBRTC_ARCH_ARM64"] = True @@ -139,10 +131,6 @@ if CONFIG["CPU_ARCH"] == "aarch64": if CONFIG["CPU_ARCH"] == "arm": - CXXFLAGS += [ - "-mfpu=neon" - ] - DEFINES["WEBRTC_ARCH_ARM"] = True DEFINES["WEBRTC_ARCH_ARM_V7"] = True DEFINES["WEBRTC_HAS_NEON"] = True @@ -191,6 +179,10 @@ if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux": if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android": + CXXFLAGS += [ + "-mfpu=neon" + ] + OS_LIBS += [ "android_support", "unwind" @@ -216,10 +208,6 @@ if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux": if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux": - CXXFLAGS += [ - "-msse2" - ] - DEFINES["_GNU_SOURCE"] = True if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux": diff --git a/third_party/libwebrtc/modules/video_capture/windows/device_info_ds.cc b/third_party/libwebrtc/modules/video_capture/windows/device_info_ds.cc index 2b01fc6930b51..f6927281f3c16 100644 --- a/third_party/libwebrtc/modules/video_capture/windows/device_info_ds.cc +++ b/third_party/libwebrtc/modules/video_capture/windows/device_info_ds.cc @@ -324,12 +324,11 @@ IBaseFilter* DeviceInfoDS::GetDeviceFilter(const char* deviceUniqueIdUTF8, deviceFound = true; hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&captureFilter); - if - FAILED(hr) { - RTC_LOG(LS_ERROR) << "Failed to bind to the selected " - "capture device " - << hr; - } + if FAILED (hr) { + RTC_LOG(LS_ERROR) << "Failed to bind to the selected " + "capture device " + << hr; + } if (productUniqueIdUTF8 && productUniqueIdUTF8Length > 0) // Get the device name diff --git a/third_party/libwebrtc/modules/video_coding/BUILD.gn b/third_party/libwebrtc/modules/video_coding/BUILD.gn index 7f5b5f320ac38..7cb713b8c6c91 100644 --- a/third_party/libwebrtc/modules/video_coding/BUILD.gn +++ b/third_party/libwebrtc/modules/video_coding/BUILD.gn @@ -308,8 +308,6 @@ rtc_library("video_coding_legacy") { visibility = [ ":video_coding_unittests" ] sources = [ "include/video_coding.h", - "jitter_buffer.cc", - "jitter_buffer.h", "receiver.cc", "receiver.h", "video_coding_impl.cc", @@ -351,6 +349,7 @@ rtc_library("video_coding_legacy") { "deprecated:deprecated_decoding_state", "deprecated:deprecated_event_wrapper", "deprecated:deprecated_frame_buffer", + "deprecated:deprecated_jitter_buffer", "deprecated:deprecated_jitter_buffer_common", "deprecated:deprecated_packet", "deprecated:deprecated_session_info", @@ -833,10 +832,6 @@ if (rtc_include_tests) { rtc_library("video_codecs_test_framework") { testonly = true sources = [ - "codecs/test/video_codec_analyzer.cc", - "codecs/test/video_codec_analyzer.h", - "codecs/test/video_codec_stats_impl.cc", - "codecs/test/video_codec_stats_impl.h", "codecs/test/video_codec_unittest.cc", "codecs/test/video_codec_unittest.h", "codecs/test/videoprocessor.cc", @@ -926,8 +921,6 @@ if (rtc_include_tests) { rtc_library("videocodec_test_impl") { testonly = true sources = [ - "codecs/test/video_codec_tester_impl.cc", - "codecs/test/video_codec_tester_impl.h", "codecs/test/videocodec_test_fixture_impl.cc", "codecs/test/videocodec_test_fixture_impl.h", ] @@ -939,20 +932,12 @@ if (rtc_include_tests) { ":videocodec_test_stats_impl", ":webrtc_vp9_helpers", "../../api:array_view", - "../../api:video_codec_tester_api", "../../api:videocodec_test_fixture_api", - "../../api/task_queue:default_task_queue_factory", - "../../api/task_queue:task_queue", "../../api/test/metrics:global_metrics_logger_and_exporter", "../../api/test/metrics:metric", "../../api/test/video:function_video_factory", "../../api/transport:field_trial_based_config", - "../../api/units:frequency", - "../../api/units:time_delta", - "../../api/units:timestamp", - "../../api/video:encoded_image", "../../api/video:video_bitrate_allocation", - "../../api/video:video_frame", "../../api/video_codecs:video_codecs_api", "../../api/video_codecs:video_decoder_factory_template", "../../api/video_codecs:video_decoder_factory_template_dav1d_adapter", @@ -972,7 +957,6 @@ if (rtc_include_tests) { "../../rtc_base:checks", "../../rtc_base:logging", "../../rtc_base:rtc_base_tests_utils", - "../../rtc_base:rtc_event", "../../rtc_base:stringutils", "../../rtc_base:task_queue_for_test", "../../rtc_base:timeutils", @@ -1009,6 +993,93 @@ if (rtc_include_tests) { ] } + rtc_library("video_codec_tester") { + testonly = true + sources = [ + "codecs/test/video_codec_analyzer.cc", + "codecs/test/video_codec_analyzer.h", + "codecs/test/video_codec_stats_impl.cc", + "codecs/test/video_codec_stats_impl.h", + "codecs/test/video_codec_tester_impl.cc", + "codecs/test/video_codec_tester_impl.h", + ] + + deps = [ + ":video_coding_utility", + "../../api:sequence_checker", + "../../api:video_codec_stats_api", + "../../api:video_codec_tester_api", + "../../api/numerics:numerics", + "../../api/task_queue:default_task_queue_factory", + "../../api/test/metrics:metrics_logger", + "../../api/units:data_rate", + "../../api/units:frequency", + "../../api/units:time_delta", + "../../api/units:timestamp", + "../../api/video:encoded_image", + "../../api/video:resolution", + "../../api/video:video_codec_constants", + "../../api/video:video_frame", + "../../rtc_base:checks", + "../../rtc_base:rtc_event", + "../../rtc_base:task_queue_for_test", + "../../rtc_base:timeutils", + "../../rtc_base/system:no_unique_address", + "../../system_wrappers", + "../../test:video_test_support", + "//third_party/libyuv", + ] + + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + } + + rtc_test("video_codec_perf_tests") { + testonly = true + + sources = [ "codecs/test/video_codec_test.cc" ] + + deps = [ + ":video_codec_interface", + ":video_codec_tester", + "../../api:create_video_codec_tester_api", + "../../api:video_codec_tester_api", + "../../api:videocodec_test_stats_api", + "../../api/test/metrics:global_metrics_logger_and_exporter", + "../../api/units:data_rate", + "../../api/units:frequency", + "../../api/video:encoded_image", + "../../api/video:resolution", + "../../api/video:video_frame", + "../../api/video_codecs:scalability_mode", + "../../api/video_codecs:video_codecs_api", + "../../media:rtc_internal_video_codecs", + "../../rtc_base:logging", + "../../test:fileutils", + "../../test:test_main", + "../../test:test_support", + "../../test:video_test_support", + "../rtp_rtcp:rtp_rtcp_format", + "svc:scalability_mode_util", + "//third_party/libyuv", + ] + + if (is_android) { + use_default_launcher = false + deps += [ + ":android_codec_factory_helper", + "../../sdk/android:hwcodecs_java", + "//modules/audio_device:audio_device_java", + "//sdk/android:native_test_jni_onload", + "//testing/android/native_test:native_test_support", + ] + shard_timeout = 900 + } + + absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ] + + data = [ "../../resources/FourPeople_1280x720_30.yuv" ] + } + rtc_library("video_coding_modules_tests") { testonly = true defines = [] @@ -1016,7 +1087,6 @@ if (rtc_include_tests) { sources = [ "codecs/h264/test/h264_impl_unittest.cc", "codecs/multiplex/test/multiplex_adapter_unittest.cc", - "codecs/test/video_codec_test.cc", "codecs/test/video_encoder_decoder_instantiation_tests.cc", "codecs/test/videocodec_test_av1.cc", "codecs/test/videocodec_test_libvpx.cc", @@ -1045,28 +1115,20 @@ if (rtc_include_tests) { ":webrtc_vp9", ":webrtc_vp9_helpers", "../../api:create_frame_generator", - "../../api:create_video_codec_tester_api", "../../api:create_videocodec_test_fixture_api", "../../api:frame_generator_api", "../../api:mock_video_codec_factory", "../../api:mock_video_decoder", "../../api:mock_video_encoder", "../../api:scoped_refptr", - "../../api:video_codec_tester_api", "../../api:videocodec_test_fixture_api", "../../api:videocodec_test_stats_api", "../../api/test/metrics:global_metrics_logger_and_exporter", "../../api/test/video:function_video_factory", - "../../api/units:data_rate", - "../../api/units:frequency", "../../api/video:encoded_image", - "../../api/video:resolution", "../../api/video:video_frame", "../../api/video:video_rtp_headers", - "../../api/video_codecs:builtin_video_decoder_factory", - "../../api/video_codecs:builtin_video_encoder_factory", "../../api/video_codecs:rtc_software_fallback_wrappers", - "../../api/video_codecs:scalability_mode", "../../api/video_codecs:video_codecs_api", "../../common_video", "../../common_video/test:utilities", @@ -1083,14 +1145,12 @@ if (rtc_include_tests) { "../../test:fileutils", "../../test:test_support", "../../test:video_test_common", - "../../test:video_test_support", "../rtp_rtcp:rtp_rtcp_format", "codecs/av1:dav1d_decoder", "svc:scalability_mode_util", "//third_party/libyuv", ] absl_deps = [ - "//third_party/abseil-cpp/absl/functional:any_invocable", "//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/types:optional", ] @@ -1145,7 +1205,6 @@ if (rtc_include_tests) { "h264_sprop_parameter_sets_unittest.cc", "h264_sps_pps_tracker_unittest.cc", "histogram_unittest.cc", - "jitter_buffer_unittest.cc", "loss_notification_controller_unittest.cc", "nack_requester_unittest.cc", "packet_buffer_unittest.cc", @@ -1153,8 +1212,6 @@ if (rtc_include_tests) { "rtp_frame_reference_finder_unittest.cc", "rtp_vp8_ref_finder_unittest.cc", "rtp_vp9_ref_finder_unittest.cc", - "test/stream_generator.cc", - "test/stream_generator.h", "utility/bandwidth_quality_scaler_unittest.cc", "utility/decoded_frames_history_unittest.cc", "utility/frame_dropper_unittest.cc", @@ -1187,6 +1244,7 @@ if (rtc_include_tests) { ":packet_buffer", ":simulcast_test_fixture_impl", ":video_codec_interface", + ":video_codec_tester", ":video_codecs_test_framework", ":video_coding", ":video_coding_legacy", @@ -1212,7 +1270,6 @@ if (rtc_include_tests) { "../../api:videocodec_test_fixture_api", "../../api/task_queue", "../../api/task_queue:default_task_queue_factory", - "../../api/task_queue/test:mock_task_queue_base", "../../api/test/video:function_video_factory", "../../api/units:data_size", "../../api/units:frequency", @@ -1273,6 +1330,7 @@ if (rtc_include_tests) { "deprecated:deprecated_jitter_buffer_common", "deprecated:deprecated_packet", "deprecated:deprecated_session_info", + "deprecated:deprecated_stream_generator", "svc:scalability_structure_tests", "svc:svc_rate_allocator_tests", "timing:jitter_estimator", diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index e5ea964f6c5b8..b16d4b2401089 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -224,7 +224,7 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings, NumberOfThreads(cfg_.g_w, cfg_.g_h, settings.number_of_cores); cfg_.g_timebase.num = 1; cfg_.g_timebase.den = kRtpTicksPerSecond; - cfg_.rc_target_bitrate = encoder_settings_.maxBitrate; // kilobits/sec. + cfg_.rc_target_bitrate = encoder_settings_.startBitrate; // kilobits/sec. cfg_.g_input_bit_depth = kBitDepth; cfg_.kf_mode = AOM_KF_DISABLED; cfg_.rc_min_quantizer = kQpMin; diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc index cca8c58439e88..09bf1bf1cacec 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc @@ -39,7 +39,7 @@ VideoCodec DefaultCodecSettings() { codec_settings.width = 320; codec_settings.height = 180; codec_settings.maxFramerate = 30; - codec_settings.maxBitrate = 1000; + codec_settings.startBitrate = 1000; codec_settings.qpMax = 63; return codec_settings; } @@ -145,7 +145,7 @@ TEST(LibaomAv1EncoderTest, SetsEndOfPictureForLastFrameInTemporalUnit) { VideoCodec codec_settings = DefaultCodecSettings(); // Configure encoder with 3 spatial layers. codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1); - codec_settings.maxBitrate = allocation.get_sum_kbps(); + codec_settings.startBitrate = allocation.get_sum_kbps(); ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), WEBRTC_VIDEO_CODEC_OK); @@ -175,7 +175,7 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) { // Odd width and height values should not make encoder crash. codec_settings.width = 623; codec_settings.height = 405; - codec_settings.maxBitrate = allocation.get_sum_kbps(); + codec_settings.startBitrate = allocation.get_sum_kbps(); ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), WEBRTC_VIDEO_CODEC_OK); encoder->SetRates(VideoEncoder::RateControlParameters( @@ -234,7 +234,7 @@ TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) { allocation.SetBitrate(2, 0, 30000); std::unique_ptr encoder = CreateLibaomAv1Encoder(); VideoCodec codec_settings = DefaultCodecSettings(); - codec_settings.maxBitrate = allocation.get_sum_kbps(); + codec_settings.startBitrate = allocation.get_sum_kbps(); ASSERT_GT(codec_settings.width, 4); // Configure encoder with 3 spatial layers. codec_settings.SetScalabilityMode(ScalabilityMode::kL3T1); @@ -324,14 +324,14 @@ TEST(LibaomAv1EncoderTest, AdheresToTargetBitrateDespiteUnevenFrameTiming) { std::unique_ptr encoder = CreateLibaomAv1Encoder(); VideoCodec codec_settings = DefaultCodecSettings(); codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1); - codec_settings.maxBitrate = 300; // kbps + codec_settings.startBitrate = 300; // kbps codec_settings.width = 320; codec_settings.height = 180; ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), WEBRTC_VIDEO_CODEC_OK); const int kFps = 30; - const int kTargetBitrateBps = codec_settings.maxBitrate * 1000; + const int kTargetBitrateBps = codec_settings.startBitrate * 1000; VideoEncoder::RateControlParameters rate_parameters; rate_parameters.framerate_fps = kFps; rate_parameters.bitrate.SetBitrate(/*spatial_index=*/0, 0, kTargetBitrateBps); diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_analyzer.h b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_analyzer.h index 8b5089136b450..29ca8ee2ffe20 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_analyzer.h +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_analyzer.h @@ -21,7 +21,6 @@ #include "api/video/resolution.h" #include "api/video/video_frame.h" #include "modules/video_coding/codecs/test/video_codec_stats_impl.h" -#include "rtc_base/synchronization/mutex.h" #include "rtc_base/system/no_unique_address.h" #include "rtc_base/task_queue_for_test.h" diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.cc index 3d9ba0003fd76..9808e2a60112e 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.cc @@ -13,7 +13,7 @@ #include #include "api/numerics/samples_stats_counter.h" -#include "api/test/metrics/global_metrics_logger_and_exporter.h" +#include "api/test/metrics/metrics_logger.h" #include "rtc_base/checks.h" #include "rtc_base/time_utils.h" @@ -256,89 +256,6 @@ Stream VideoCodecStatsImpl::Aggregate(const std::vector& frames) const { return stream; } -void VideoCodecStatsImpl::LogMetrics( - MetricsLogger* logger, - const Stream& stream, - std::string test_case_name, - std::map metadata) const { - logger->LogMetric("width", test_case_name, stream.width, Unit::kCount, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("height", test_case_name, stream.height, Unit::kCount, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric( - "frame_size_bytes", test_case_name, stream.frame_size_bytes, Unit::kBytes, - webrtc::test::ImprovementDirection::kNeitherIsBetter, metadata); - - logger->LogMetric("keyframe", test_case_name, stream.keyframe, Unit::kCount, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("qp", test_case_name, stream.qp, Unit::kUnitless, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("encode_time_ms", test_case_name, stream.encode_time_ms, - Unit::kMilliseconds, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("decode_time_ms", test_case_name, stream.decode_time_ms, - Unit::kMilliseconds, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("target_bitrate_kbps", test_case_name, - stream.target_bitrate_kbps, Unit::kKilobitsPerSecond, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("target_framerate_fps", test_case_name, - stream.target_framerate_fps, Unit::kHertz, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("encoded_bitrate_kbps", test_case_name, - stream.encoded_bitrate_kbps, Unit::kKilobitsPerSecond, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("encoded_framerate_fps", test_case_name, - stream.encoded_framerate_fps, Unit::kHertz, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("bitrate_mismatch_pct", test_case_name, - stream.bitrate_mismatch_pct, Unit::kPercent, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("framerate_mismatch_pct", test_case_name, - stream.framerate_mismatch_pct, Unit::kPercent, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("transmission_time_ms", test_case_name, - stream.transmission_time_ms, Unit::kMilliseconds, - webrtc::test::ImprovementDirection::kSmallerIsBetter, - metadata); - - logger->LogMetric("psnr_y_db", test_case_name, stream.psnr.y, Unit::kUnitless, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("psnr_u_db", test_case_name, stream.psnr.u, Unit::kUnitless, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); - - logger->LogMetric("psnr_v_db", test_case_name, stream.psnr.v, Unit::kUnitless, - webrtc::test::ImprovementDirection::kBiggerIsBetter, - metadata); -} - void VideoCodecStatsImpl::AddFrame(const Frame& frame) { FrameId frame_id{.timestamp_rtp = frame.timestamp_rtp, .spatial_idx = frame.spatial_idx}; diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.h b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.h index 56067610f0d5f..77471d2ecd9c9 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.h +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl.h @@ -29,12 +29,6 @@ class VideoCodecStatsImpl : public VideoCodecStats { Stream Aggregate(const std::vector& frames) const override; - void LogMetrics( - MetricsLogger* logger, - const Stream& stream, - std::string test_case_name, - std::map metadata = {}) const override; - void AddFrame(const Frame& frame); // Returns raw pointers to previously added frame. If frame does not exist, diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc index a0d3a5a41b43b..af52f45ff45d6 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_test.cc @@ -18,16 +18,17 @@ #include "absl/functional/any_invocable.h" #include "api/test/create_video_codec_tester.h" #include "api/test/metrics/global_metrics_logger_and_exporter.h" +#include "api/test/video_codec_tester.h" #include "api/test/videocodec_test_stats.h" #include "api/units/data_rate.h" #include "api/units/frequency.h" +#include "api/video/encoded_image.h" #include "api/video/i420_buffer.h" #include "api/video/resolution.h" +#include "api/video/video_frame.h" #include "api/video_codecs/scalability_mode.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" -#include "common_video/libyuv/include/webrtc_libyuv.h" -#include "media/base/media_constants.h" #include "media/engine/internal_decoder_factory.h" #include "media/engine/internal_encoder_factory.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" @@ -36,7 +37,7 @@ #if defined(WEBRTC_ANDROID) #include "modules/video_coding/codecs/test/android_codec_factory_helper.h" #endif -#include "rtc_base/strings/string_builder.h" +#include "rtc_base/logging.h" #include "test/gtest.h" #include "test/testsupport/file_utils.h" #include "test/testsupport/frame_reader.h" @@ -83,17 +84,17 @@ struct EncodingSettings { bool IsSameSettings(const EncodingSettings& other) const { if (scalability_mode != other.scalability_mode) { - return true; + return false; } for (auto [layer_id, layer] : layer_settings) { const auto& other_layer = other.layer_settings.at(layer_id); if (layer.resolution != other_layer.resolution) { - return true; + return false; } } - return false; + return true; } bool IsSameRate(const EncodingSettings& other) const { @@ -101,11 +102,11 @@ struct EncodingSettings { const auto& other_layer = other.layer_settings.at(layer_id); if (layer.bitrate != other_layer.bitrate || layer.framerate != other_layer.framerate) { - return true; + return false; } } - return false; + return true; } }; @@ -462,11 +463,29 @@ std::unique_ptr RunEncodeDecodeTest( std::unique_ptr video_source = CreateVideoSource(video_info, frame_settings, num_frames); - // TODO(webrtc:14852): On platforms where only encoder or decoder is - // available, substitute absent codec with software implementation. std::unique_ptr encoder = CreateEncoder(codec_type, codec_impl, frame_settings); + if (encoder == nullptr) { + return nullptr; + } + std::unique_ptr decoder = CreateDecoder(codec_type, codec_impl); + if (decoder == nullptr) { + // If platform decoder is not available try built-in one. + if (codec_impl == "builtin") { + return nullptr; + } + + decoder = CreateDecoder(codec_type, "builtin"); + if (decoder == nullptr) { + return nullptr; + } + } + + RTC_LOG(LS_INFO) << "Encoder implementation: " + << encoder->encoder()->GetEncoderInfo().implementation_name; + RTC_LOG(LS_INFO) << "Decoder implementation: " + << decoder->decoder()->GetDecoderInfo().implementation_name; VideoCodecTester::EncoderSettings encoder_settings; encoder_settings.pacing.mode = @@ -509,6 +528,12 @@ std::unique_ptr RunEncodeTest( std::unique_ptr encoder = CreateEncoder(codec_type, codec_impl, frame_settings); + if (encoder == nullptr) { + return nullptr; + } + + RTC_LOG(LS_INFO) << "Encoder implementation: " + << encoder->encoder()->GetEncoderInfo().implementation_name; VideoCodecTester::EncoderSettings encoder_settings; encoder_settings.pacing.mode = @@ -551,7 +576,7 @@ class SpatialQualityTest : public ::testing::TestWithParam< } }; -TEST_P(SpatialQualityTest, DISABLED_SpatialQuality) { +TEST_P(SpatialQualityTest, SpatialQuality) { auto [codec_type, codec_impl, video_info, coding_settings] = GetParam(); auto [width, height, framerate_fps, bitrate_kbps, psnr] = coding_settings; @@ -571,13 +596,16 @@ TEST_P(SpatialQualityTest, DISABLED_SpatialQuality) { codec_type, codec_impl, video_info, frame_settings, num_frames, /*save_codec_input=*/false, /*save_codec_output=*/false); - std::vector frames = stats->Slice(); - SetTargetRates(frame_settings, frames); - VideoCodecStats::Stream stream = stats->Aggregate(frames); - EXPECT_GE(stream.psnr.y.GetAverage(), psnr); + VideoCodecStats::Stream stream; + if (stats != nullptr) { + std::vector frames = stats->Slice(); + SetTargetRates(frame_settings, frames); + stream = stats->Aggregate(frames); + EXPECT_GE(stream.psnr.y.GetAverage(), psnr); + } - stats->LogMetrics( - GetGlobalMetricsLogger(), stream, + stream.LogMetrics( + GetGlobalMetricsLogger(), ::testing::UnitTest::GetInstance()->current_test_info()->name(), /*metadata=*/ {{"codec_type", codec_type}, @@ -625,7 +653,7 @@ class BitrateAdaptationTest } }; -TEST_P(BitrateAdaptationTest, DISABLED_BitrateAdaptation) { +TEST_P(BitrateAdaptationTest, BitrateAdaptation) { auto [codec_type, codec_impl, video_info, bitrate_kbps] = GetParam(); int duration_s = 10; // Duration of fixed rate interval. @@ -650,15 +678,18 @@ TEST_P(BitrateAdaptationTest, DISABLED_BitrateAdaptation) { codec_type, codec_impl, video_info, frame_settings, num_frames, /*save_codec_input=*/false, /*save_codec_output=*/false); - std::vector frames = - stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); - SetTargetRates(frame_settings, frames); - VideoCodecStats::Stream stream = stats->Aggregate(frames); - EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); - EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); + VideoCodecStats::Stream stream; + if (stats != nullptr) { + std::vector frames = + stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); + SetTargetRates(frame_settings, frames); + stream = stats->Aggregate(frames); + EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); + EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); + } - stats->LogMetrics( - GetGlobalMetricsLogger(), stream, + stream.LogMetrics( + GetGlobalMetricsLogger(), ::testing::UnitTest::GetInstance()->current_test_info()->name(), /*metadata=*/ {{"codec_type", codec_type}, @@ -698,7 +729,7 @@ class FramerateAdaptationTest } }; -TEST_P(FramerateAdaptationTest, DISABLED_FramerateAdaptation) { +TEST_P(FramerateAdaptationTest, FramerateAdaptation) { auto [codec_type, codec_impl, video_info, framerate_fps] = GetParam(); int duration_s = 10; // Duration of fixed rate interval. @@ -724,15 +755,18 @@ TEST_P(FramerateAdaptationTest, DISABLED_FramerateAdaptation) { codec_type, codec_impl, video_info, frame_settings, num_frames, /*save_codec_input=*/false, /*save_codec_output=*/false); - std::vector frames = - stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); - SetTargetRates(frame_settings, frames); - VideoCodecStats::Stream stream = stats->Aggregate(frames); - EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); - EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); + VideoCodecStats::Stream stream; + if (stats != nullptr) { + std::vector frames = + stats->Slice(VideoCodecStats::Filter{.first_frame = first_frame}); + SetTargetRates(frame_settings, frames); + stream = stats->Aggregate(frames); + EXPECT_NEAR(stream.bitrate_mismatch_pct.GetAverage(), 0, 10); + EXPECT_NEAR(stream.framerate_mismatch_pct.GetAverage(), 0, 10); + } - stats->LogMetrics( - GetGlobalMetricsLogger(), stream, + stream.LogMetrics( + GetGlobalMetricsLogger(), ::testing::UnitTest::GetInstance()->current_test_info()->name(), /*metadata=*/ {{"codec_type", codec_type}, diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc index 459ef4f0dd4f7..524134bd4216a 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc @@ -15,8 +15,6 @@ #include #include -#include "api/task_queue/task_queue_factory.h" -#include "api/task_queue/test/mock_task_queue_base.h" #include "api/units/frequency.h" #include "api/units/time_delta.h" #include "api/video/encoded_image.h" @@ -135,20 +133,6 @@ class MockEncoder : public Encoder { MOCK_METHOD(void, Flush, (), (override)); }; -class MockTaskQueueFactory : public TaskQueueFactory { - public: - explicit MockTaskQueueFactory(TaskQueueBase& task_queue) - : task_queue_(task_queue) {} - - std::unique_ptr CreateTaskQueue( - absl::string_view name, - Priority priority) const override { - return std::unique_ptr(&task_queue_); - } - - protected: - TaskQueueBase& task_queue_; -}; } // namespace class VideoCodecTesterImplPacingTest diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc index e56e8a92af4cc..7543372e216b7 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc @@ -518,7 +518,6 @@ void VideoCodecTestFixtureImpl::AnalyzeAllFrames( const std::vector* rc_thresholds, const std::vector* quality_thresholds, const BitstreamThresholds* bs_thresholds) { - for (size_t rate_profile_idx = 0; rate_profile_idx < rate_profiles.size(); ++rate_profile_idx) { const size_t first_frame_num = rate_profiles[rate_profile_idx].frame_num; @@ -799,13 +798,12 @@ bool VideoCodecTestFixtureImpl::SetUpAndInitObjects( } } - task_queue->SendTask( - [this]() { - processor_ = std::make_unique( - encoder_.get(), &decoders_, source_frame_reader_.get(), config_, - &stats_, &encoded_frame_writers_, - decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_); - }); + task_queue->SendTask([this]() { + processor_ = std::make_unique( + encoder_.get(), &decoders_, source_frame_reader_.get(), config_, + &stats_, &encoded_frame_writers_, + decoded_frame_writers_.empty() ? nullptr : &decoded_frame_writers_); + }); return true; } diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/videoprocessor_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/videoprocessor_unittest.cc index f1774af5df125..40cb5b6395cca 100644 --- a/third_party/libwebrtc/modules/video_coding/codecs/test/videoprocessor_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/videoprocessor_unittest.cc @@ -51,12 +51,11 @@ class VideoProcessorTest : public ::testing::Test { decoders_.push_back(std::unique_ptr(decoder_mock_)); ExpectInit(); - q_.SendTask( - [this] { - video_processor_ = std::make_unique( - &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_, - &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr); - }); + q_.SendTask([this] { + video_processor_ = std::make_unique( + &encoder_mock_, &decoders_, &frame_reader_mock_, config_, &stats_, + &encoded_frame_writers_, /*decoded_frame_writers=*/nullptr); + }); } ~VideoProcessorTest() { diff --git a/third_party/libwebrtc/modules/video_coding/deprecated/BUILD.gn b/third_party/libwebrtc/modules/video_coding/deprecated/BUILD.gn index 5859902165156..43f6959ce8ccd 100644 --- a/third_party/libwebrtc/modules/video_coding/deprecated/BUILD.gn +++ b/third_party/libwebrtc/modules/video_coding/deprecated/BUILD.gn @@ -41,6 +41,33 @@ rtc_library("deprecated_jitter_buffer_common") { sources = [ "jitter_buffer_common.h" ] } +rtc_library("deprecated_jitter_buffer") { + sources = [ + "jitter_buffer.cc", + "jitter_buffer.h", + ] + deps = [ + ":deprecated_decoding_state", + ":deprecated_event_wrapper", + ":deprecated_frame_buffer", + ":deprecated_jitter_buffer_common", + ":deprecated_packet", + "../../../api:field_trials_view", + "../../../api/units:timestamp", + "../../../modules:module_api", + "../../../modules:module_api_public", + "../../../modules/video_coding:video_codec_interface", + "../../../modules/video_coding/timing:inter_frame_delay_variation_calculator", + "../../../modules/video_coding/timing:jitter_estimator", + "../../../rtc_base:checks", + "../../../rtc_base:logging", + "../../../rtc_base:macromagic", + "../../../rtc_base/synchronization:mutex", + "../../../system_wrappers", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] +} + rtc_library("deprecated_frame_buffer") { sources = [ "frame_buffer.cc", @@ -92,20 +119,38 @@ rtc_library("deprecated_session_info") { absl_deps = [ "//third_party/abseil-cpp/absl/types:variant" ] } +rtc_library("deprecated_stream_generator") { + deps = [ + ":deprecated_packet", + "../../../rtc_base:checks", + ] + sources = [ + "stream_generator.cc", + "stream_generator.h", + ] +} + rtc_library("deprecated_unittests") { testonly = true sources = [ "decoding_state_unittest.cc", + "jitter_buffer_unittest.cc", "session_info_unittest.cc", ] visibility += [ "../../../modules/*" ] deps = [ ":deprecated_decoding_state", ":deprecated_frame_buffer", + ":deprecated_jitter_buffer", ":deprecated_packet", ":deprecated_session_info", + ":deprecated_stream_generator", + "../../../common_video", "../../../modules/rtp_rtcp:rtp_video_header", "../../../modules/video_coding:codec_globals_headers", + "../../../system_wrappers", + "../../../test:scoped_key_value_config", "../../../test:test_support", ] + absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] } diff --git a/third_party/libwebrtc/modules/video_coding/jitter_buffer.cc b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.cc similarity index 99% rename from third_party/libwebrtc/modules/video_coding/jitter_buffer.cc rename to third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.cc index e417ab30488b6..bae4bac9f80a3 100644 --- a/third_party/libwebrtc/modules/video_coding/jitter_buffer.cc +++ b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.cc @@ -7,7 +7,7 @@ * 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/jitter_buffer.h" +#include "modules/video_coding/deprecated/jitter_buffer.h" #include #include @@ -17,8 +17,6 @@ #include "modules/video_coding/deprecated/frame_buffer.h" #include "modules/video_coding/deprecated/jitter_buffer_common.h" #include "modules/video_coding/deprecated/packet.h" -#include "modules/video_coding/include/video_coding.h" -#include "modules/video_coding/internal_defines.h" #include "modules/video_coding/timing/inter_frame_delay_variation_calculator.h" #include "modules/video_coding/timing/jitter_estimator.h" #include "rtc_base/checks.h" @@ -186,6 +184,10 @@ bool VCMJitterBuffer::Running() const { void VCMJitterBuffer::Flush() { MutexLock lock(&mutex_); + FlushInternal(); +} + +void VCMJitterBuffer::FlushInternal() { decodable_frames_.Reset(&free_frames_); incomplete_frames_.Reset(&free_frames_); last_decoded_state_.Reset(); // TODO(mikhal): sync reset. @@ -378,7 +380,7 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet, RTC_LOG(LS_WARNING) << num_consecutive_old_packets_ << " consecutive old packets received. Flushing the jitter buffer."; - Flush(); + FlushInternal(); return kFlushIndicator; } return kOldPacket; diff --git a/third_party/libwebrtc/modules/video_coding/jitter_buffer.h b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.h similarity index 89% rename from third_party/libwebrtc/modules/video_coding/jitter_buffer.h rename to third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.h index 6563c56e872c6..49af9c7b1e890 100644 --- a/third_party/libwebrtc/modules/video_coding/jitter_buffer.h +++ b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_JITTER_BUFFER_H_ -#define MODULES_VIDEO_CODING_JITTER_BUFFER_H_ +#ifndef MODULES_VIDEO_CODING_DEPRECATED_JITTER_BUFFER_H_ +#define MODULES_VIDEO_CODING_DEPRECATED_JITTER_BUFFER_H_ #include #include @@ -23,7 +23,6 @@ #include "modules/video_coding/deprecated/decoding_state.h" #include "modules/video_coding/deprecated/event_wrapper.h" #include "modules/video_coding/deprecated/jitter_buffer_common.h" -#include "modules/video_coding/include/video_coding.h" #include "modules/video_coding/include/video_coding_defines.h" #include "modules/video_coding/timing/inter_frame_delay_variation_calculator.h" #include "modules/video_coding/timing/jitter_estimator.h" @@ -80,55 +79,59 @@ class VCMJitterBuffer { VCMJitterBuffer& operator=(const VCMJitterBuffer&) = delete; // Initializes and starts jitter buffer. - void Start(); + void Start() RTC_LOCKS_EXCLUDED(mutex_); // Signals all internal events and stops the jitter buffer. - void Stop(); + void Stop() RTC_LOCKS_EXCLUDED(mutex_); // Returns true if the jitter buffer is running. - bool Running() const; + bool Running() const RTC_LOCKS_EXCLUDED(mutex_); // Empty the jitter buffer of all its data. - void Flush(); + void Flush() RTC_LOCKS_EXCLUDED(mutex_); // Gets number of packets received. - int num_packets() const; + int num_packets() const RTC_LOCKS_EXCLUDED(mutex_); // Gets number of duplicated packets received. - int num_duplicated_packets() const; + int num_duplicated_packets() const RTC_LOCKS_EXCLUDED(mutex_); // Wait `max_wait_time_ms` for a complete frame to arrive. // If found, a pointer to the frame is returned. Returns nullptr otherwise. - VCMEncodedFrame* NextCompleteFrame(uint32_t max_wait_time_ms); + VCMEncodedFrame* NextCompleteFrame(uint32_t max_wait_time_ms) + RTC_LOCKS_EXCLUDED(mutex_); // Extract frame corresponding to input timestamp. // Frame will be set to a decoding state. - VCMEncodedFrame* ExtractAndSetDecode(uint32_t timestamp); + VCMEncodedFrame* ExtractAndSetDecode(uint32_t timestamp) + RTC_LOCKS_EXCLUDED(mutex_); // Releases a frame returned from the jitter buffer, should be called when // done with decoding. - void ReleaseFrame(VCMEncodedFrame* frame); + void ReleaseFrame(VCMEncodedFrame* frame) RTC_LOCKS_EXCLUDED(mutex_); // Returns the time in ms when the latest packet was inserted into the frame. // Retransmitted is set to true if any of the packets belonging to the frame // has been retransmitted. int64_t LastPacketTime(const VCMEncodedFrame* frame, - bool* retransmitted) const; + bool* retransmitted) const RTC_LOCKS_EXCLUDED(mutex_); // Inserts a packet into a frame returned from GetFrame(). // If the return value is <= 0, `frame` is invalidated and the pointer must // be dropped after this function returns. - VCMFrameBufferEnum InsertPacket(const VCMPacket& packet, bool* retransmitted); + VCMFrameBufferEnum InsertPacket(const VCMPacket& packet, bool* retransmitted) + RTC_LOCKS_EXCLUDED(mutex_); // Returns the estimated jitter in milliseconds. - uint32_t EstimatedJitterMs(); + uint32_t EstimatedJitterMs() RTC_LOCKS_EXCLUDED(mutex_); void SetNackSettings(size_t max_nack_list_size, int max_packet_age_to_nack, - int max_incomplete_time_ms); + int max_incomplete_time_ms) RTC_LOCKS_EXCLUDED(mutex_); // Returns a list of the sequence numbers currently missing. - std::vector GetNackList(bool* request_key_frame); + std::vector GetNackList(bool* request_key_frame) + RTC_LOCKS_EXCLUDED(mutex_); private: class SequenceNumberLessThan { @@ -202,7 +205,8 @@ class VCMJitterBuffer { bool RecycleFramesUntilKeyFrame() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Update rolling average of packets per frame. - void UpdateAveragePacketsPerFrame(int current_number_packets_); + void UpdateAveragePacketsPerFrame(int current_number_packets_) + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); // Cleans the frame list in the JB from old/empty frames. // Should only be called prior to actual use. @@ -229,6 +233,9 @@ class VCMJitterBuffer { void RecycleFrameBuffer(VCMFrameBuffer* frame) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Empty the jitter buffer of all its data. + void FlushInternal() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + Clock* clock_; // If we are running (have started) or not. bool running_; @@ -272,4 +279,4 @@ class VCMJitterBuffer { }; } // namespace webrtc -#endif // MODULES_VIDEO_CODING_JITTER_BUFFER_H_ +#endif // MODULES_VIDEO_CODING_DEPRECATED_JITTER_BUFFER_H_ diff --git a/third_party/libwebrtc/modules/video_coding/jitter_buffer_unittest.cc b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer_unittest.cc similarity index 99% rename from third_party/libwebrtc/modules/video_coding/jitter_buffer_unittest.cc rename to third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer_unittest.cc index 89f75e7a93c1a..81483a1e2c804 100644 --- a/third_party/libwebrtc/modules/video_coding/jitter_buffer_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/deprecated/jitter_buffer_unittest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/jitter_buffer.h" +#include "modules/video_coding/deprecated/jitter_buffer.h" #include #include @@ -19,10 +19,8 @@ #include "common_video/h264/h264_common.h" #include "modules/video_coding/deprecated/frame_buffer.h" #include "modules/video_coding/deprecated/packet.h" -#include "modules/video_coding/media_opt_util.h" -#include "modules/video_coding/test/stream_generator.h" +#include "modules/video_coding/deprecated/stream_generator.h" #include "system_wrappers/include/clock.h" -#include "system_wrappers/include/metrics.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/scoped_key_value_config.h" diff --git a/third_party/libwebrtc/modules/video_coding/test/stream_generator.cc b/third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.cc similarity index 96% rename from third_party/libwebrtc/modules/video_coding/test/stream_generator.cc rename to third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.cc index c136f2efcf663..503ada2b37b08 100644 --- a/third_party/libwebrtc/modules/video_coding/test/stream_generator.cc +++ b/third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.cc @@ -8,14 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/test/stream_generator.h" +#include "modules/video_coding/deprecated/stream_generator.h" #include #include #include "modules/video_coding/deprecated/packet.h" -#include "test/gtest.h" +#include "rtc_base/checks.h" namespace webrtc { @@ -55,7 +55,7 @@ VCMPacket StreamGenerator::GeneratePacket(uint16_t sequence_number, bool first_packet, bool marker_bit, VideoFrameType type) { - EXPECT_LT(size, kMaxPacketSize); + RTC_CHECK_LT(size, kMaxPacketSize); VCMPacket packet; packet.seqNum = sequence_number; packet.timestamp = timestamp; diff --git a/third_party/libwebrtc/modules/video_coding/test/stream_generator.h b/third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.h similarity index 92% rename from third_party/libwebrtc/modules/video_coding/test/stream_generator.h rename to third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.h index 1b6bb12df8828..1a86f6993740f 100644 --- a/third_party/libwebrtc/modules/video_coding/test/stream_generator.h +++ b/third_party/libwebrtc/modules/video_coding/deprecated/stream_generator.h @@ -7,8 +7,8 @@ * 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_TEST_STREAM_GENERATOR_H_ -#define MODULES_VIDEO_CODING_TEST_STREAM_GENERATOR_H_ +#ifndef MODULES_VIDEO_CODING_DEPRECATED_STREAM_GENERATOR_H_ +#define MODULES_VIDEO_CODING_DEPRECATED_STREAM_GENERATOR_H_ #include @@ -71,4 +71,4 @@ class StreamGenerator { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_TEST_STREAM_GENERATOR_H_ +#endif // MODULES_VIDEO_CODING_DEPRECATED_STREAM_GENERATOR_H_ diff --git a/third_party/libwebrtc/modules/video_coding/packet_buffer.cc b/third_party/libwebrtc/modules/video_coding/packet_buffer.cc index 9f1bb211c56e2..be45db6ef040b 100644 --- a/third_party/libwebrtc/modules/video_coding/packet_buffer.cc +++ b/third_party/libwebrtc/modules/video_coding/packet_buffer.cc @@ -325,7 +325,7 @@ std::vector> PacketBuffer::FindFrames( // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 if (is_h264_descriptor && (buffer_[start_index] == nullptr || - buffer_[start_index]->timestamp != frame_timestamp)) { + buffer_[start_index]->timestamp != frame_timestamp)) { break; } diff --git a/third_party/libwebrtc/modules/video_coding/receiver.h b/third_party/libwebrtc/modules/video_coding/receiver.h index afc4b9c563a00..fcadf607a06f9 100644 --- a/third_party/libwebrtc/modules/video_coding/receiver.h +++ b/third_party/libwebrtc/modules/video_coding/receiver.h @@ -16,10 +16,10 @@ #include "api/field_trials_view.h" #include "modules/video_coding/deprecated/event_wrapper.h" +#include "modules/video_coding/deprecated/jitter_buffer.h" #include "modules/video_coding/deprecated/packet.h" #include "modules/video_coding/include/video_coding.h" #include "modules/video_coding/include/video_coding_defines.h" -#include "modules/video_coding/jitter_buffer.h" #include "modules/video_coding/timing/timing.h" namespace webrtc { diff --git a/third_party/libwebrtc/modules/video_coding/receiver_unittest.cc b/third_party/libwebrtc/modules/video_coding/receiver_unittest.cc index ef8df0757c711..7b7e423841423 100644 --- a/third_party/libwebrtc/modules/video_coding/receiver_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/receiver_unittest.cc @@ -18,8 +18,8 @@ #include "modules/video_coding/deprecated/jitter_buffer_common.h" #include "modules/video_coding/deprecated/packet.h" +#include "modules/video_coding/deprecated/stream_generator.h" #include "modules/video_coding/encoded_frame.h" -#include "modules/video_coding/test/stream_generator.h" #include "modules/video_coding/timing/timing.h" #include "rtc_base/checks.h" #include "system_wrappers/include/clock.h" diff --git a/third_party/libwebrtc/modules/video_coding/rtp_frame_reference_finder.cc b/third_party/libwebrtc/modules/video_coding/rtp_frame_reference_finder.cc index 3d6543b850f8b..b73fcfe9d5029 100644 --- a/third_party/libwebrtc/modules/video_coding/rtp_frame_reference_finder.cc +++ b/third_party/libwebrtc/modules/video_coding/rtp_frame_reference_finder.cc @@ -145,8 +145,7 @@ T& RtpFrameReferenceFinderImpl::GetRefFinderAs() { RtpFrameReferenceFinder::RtpFrameReferenceFinder() : RtpFrameReferenceFinder(0) {} -RtpFrameReferenceFinder::RtpFrameReferenceFinder( - int64_t picture_id_offset) +RtpFrameReferenceFinder::RtpFrameReferenceFinder(int64_t picture_id_offset) : picture_id_offset_(picture_id_offset), impl_(std::make_unique()) {} diff --git a/third_party/libwebrtc/modules/video_coding/rtp_vp9_ref_finder_unittest.cc b/third_party/libwebrtc/modules/video_coding/rtp_vp9_ref_finder_unittest.cc index 72084a73580ea..a3cb31ade5fe8 100644 --- a/third_party/libwebrtc/modules/video_coding/rtp_vp9_ref_finder_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/rtp_vp9_ref_finder_unittest.cc @@ -157,8 +157,7 @@ class HasFrameMatcher : public MatcherInterface { public: explicit HasFrameMatcher(int64_t frame_id, const std::vector& expected_refs) - : frame_id_(frame_id), - expected_refs_(expected_refs) {} + : frame_id_(frame_id), expected_refs_(expected_refs) {} bool MatchAndExplain(const FrameVector& frames, MatchResultListener* result_listener) const override { diff --git a/third_party/libwebrtc/modules/video_coding/timing/jitter_estimator.h b/third_party/libwebrtc/modules/video_coding/timing/jitter_estimator.h index a89a4bf1fd170..89dc64934b69d 100644 --- a/third_party/libwebrtc/modules/video_coding/timing/jitter_estimator.h +++ b/third_party/libwebrtc/modules/video_coding/timing/jitter_estimator.h @@ -172,7 +172,7 @@ class JitterEstimator { // TODO(bugs.webrtc.org/14381): Update `avg_frame_size_bytes_` to DataSize // when api/units have sufficient precision. - double avg_frame_size_bytes_; // Average frame size + double avg_frame_size_bytes_; // Average frame size double var_frame_size_bytes2_; // Frame size variance. Unit is bytes^2. // Largest frame size received (descending with a factor kPsi). // Used by default. diff --git a/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator.cc b/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator.cc index dc62ac674abe6..77e5508a76a6b 100644 --- a/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator.cc +++ b/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator.cc @@ -133,19 +133,24 @@ absl::optional TimestampExtrapolator::ExtrapolateLocalTime( constexpr double kRtpTicksPerMs = 90; TimeDelta diff = TimeDelta::Millis( (unwrapped_ts90khz - *prev_unwrapped_timestamp_) / kRtpTicksPerMs); - if (diff.ms() < 0) { - RTC_DCHECK_GE(prev_.ms(), -diff.ms()); + if (prev_.us() + diff.us() < 0) { + // Prevent the construction of a negative Timestamp. + // This scenario can occur when the RTP timestamp wraps around. + return absl::nullopt; } return prev_ + diff; } else if (w_[0] < 1e-3) { return start_; } else { double timestampDiff = unwrapped_ts90khz - *first_unwrapped_timestamp_; - auto diff_ms = static_cast((timestampDiff - w_[1]) / w_[0] + 0.5); - if (diff_ms < 0) { - RTC_DCHECK_GE(start_.ms(), -diff_ms); + TimeDelta diff = TimeDelta::Millis( + static_cast((timestampDiff - w_[1]) / w_[0] + 0.5)); + if (start_.us() + diff.us() < 0) { + // Prevent the construction of a negative Timestamp. + // This scenario can occur when the RTP timestamp wraps around. + return absl::nullopt; } - return start_ + TimeDelta::Millis(diff_ms); + return start_ + diff; } } diff --git a/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator_unittest.cc b/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator_unittest.cc index 0b5fd74a8e0be..d6c8fa9de1ce8 100644 --- a/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/timing/timestamp_extrapolator_unittest.cc @@ -127,12 +127,25 @@ TEST(TimestampExtrapolatorTest, NegativeRtpTimestampWrapAround) { ts_extrapolator.Update(clock.CurrentTime(), rtp); EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), Optional(clock.CurrentTime())); - // Go backwards! - rtp -= kRtpHz.hertz(); + // Go backwards! Static cast to avoid undefined behaviour with -=. + rtp -= static_cast(kRtpHz.hertz()); EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), Optional(clock.CurrentTime() - TimeDelta::Seconds(1))); } +TEST(TimestampExtrapolatorTest, NegativeRtpTimestampWrapAroundSecondScenario) { + SimulatedClock clock(Timestamp::Millis(1337)); + TimestampExtrapolator ts_extrapolator(clock.CurrentTime()); + uint32_t rtp = 0; + ts_extrapolator.Update(clock.CurrentTime(), rtp); + EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), + Optional(clock.CurrentTime())); + // Go backwards! Static cast to avoid undefined behaviour with -=. + rtp -= static_cast(kRtpHz * TimeDelta::Seconds(10)); + ts_extrapolator.Update(clock.CurrentTime(), rtp); + EXPECT_THAT(ts_extrapolator.ExtrapolateLocalTime(rtp), absl::nullopt); +} + TEST(TimestampExtrapolatorTest, Slow90KHzClock) { // This simulates a slow camera, which produces frames at 24Hz instead of // 25Hz. The extrapolator should be able to resolve this with enough data. diff --git a/third_party/libwebrtc/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc b/third_party/libwebrtc/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc index d28052e28defb..4e2c759707618 100644 --- a/third_party/libwebrtc/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/utility/bandwidth_quality_scaler_unittest.cc @@ -97,17 +97,16 @@ class BandwidthQualityScalerTest : scoped_field_trial_(GetParam()), task_queue_("BandwidthQualityScalerTestQueue"), handler_(std::make_unique()) { - task_queue_.SendTask( - [this] { - bandwidth_quality_scaler_ = - std::unique_ptr( - new BandwidthQualityScalerUnderTest(handler_.get())); - bandwidth_quality_scaler_->SetResolutionBitrateLimits( - EncoderInfoSettings:: - GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted()); - // Only for testing. Set first_timestamp_ in RateStatistics to 0. - bandwidth_quality_scaler_->ReportEncodeInfo(0, 0, 0, 0); - }); + task_queue_.SendTask([this] { + bandwidth_quality_scaler_ = + std::unique_ptr( + new BandwidthQualityScalerUnderTest(handler_.get())); + bandwidth_quality_scaler_->SetResolutionBitrateLimits( + EncoderInfoSettings:: + GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted()); + // Only for testing. Set first_timestamp_ in RateStatistics to 0. + bandwidth_quality_scaler_->ReportEncodeInfo(0, 0, 0, 0); + }); } ~BandwidthQualityScalerTest() { @@ -150,37 +149,35 @@ class BandwidthQualityScalerTest void TriggerBandwidthQualityScalerTest( const std::vector& frame_configs) { - task_queue_.SendTask( - [frame_configs, this] { - RTC_CHECK(!frame_configs.empty()); - - int total_frame_nums = 0; - for (const FrameConfig& frame_config : frame_configs) { - total_frame_nums += frame_config.frame_num; - } - - EXPECT_EQ( - kFramerateFps * kDefaultBitrateStateUpdateInterval.seconds(), - total_frame_nums); - - uint32_t time_send_to_scaler_ms_ = rtc::TimeMillis(); - for (size_t i = 0; i < frame_configs.size(); ++i) { - const FrameConfig& config = frame_configs[i]; - absl::optional - suitable_bitrate = GetDefaultSuitableBitrateLimit( - config.actual_width * config.actual_height); - EXPECT_TRUE(suitable_bitrate); - for (int j = 0; j <= config.frame_num; ++j) { - time_send_to_scaler_ms_ += kDefaultEncodeTime.ms(); - int frame_size_bytes = - GetFrameSizeBytes(config, suitable_bitrate.value()); - RTC_CHECK(frame_size_bytes > 0); - bandwidth_quality_scaler_->ReportEncodeInfo( - frame_size_bytes, time_send_to_scaler_ms_, - config.actual_width, config.actual_height); - } - } - }); + task_queue_.SendTask([frame_configs, this] { + RTC_CHECK(!frame_configs.empty()); + + int total_frame_nums = 0; + for (const FrameConfig& frame_config : frame_configs) { + total_frame_nums += frame_config.frame_num; + } + + EXPECT_EQ(kFramerateFps * kDefaultBitrateStateUpdateInterval.seconds(), + total_frame_nums); + + uint32_t time_send_to_scaler_ms_ = rtc::TimeMillis(); + for (size_t i = 0; i < frame_configs.size(); ++i) { + const FrameConfig& config = frame_configs[i]; + absl::optional suitable_bitrate = + GetDefaultSuitableBitrateLimit(config.actual_width * + config.actual_height); + EXPECT_TRUE(suitable_bitrate); + for (int j = 0; j <= config.frame_num; ++j) { + time_send_to_scaler_ms_ += kDefaultEncodeTime.ms(); + int frame_size_bytes = + GetFrameSizeBytes(config, suitable_bitrate.value()); + RTC_CHECK(frame_size_bytes > 0); + bandwidth_quality_scaler_->ReportEncodeInfo( + frame_size_bytes, time_send_to_scaler_ms_, config.actual_width, + config.actual_height); + } + } + }); } test::ScopedFieldTrials scoped_field_trial_; diff --git a/third_party/libwebrtc/modules/video_coding/utility/ivf_file_reader_unittest.cc b/third_party/libwebrtc/modules/video_coding/utility/ivf_file_reader_unittest.cc index c9cf14674b238..0e20b7f77c26d 100644 --- a/third_party/libwebrtc/modules/video_coding/utility/ivf_file_reader_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/utility/ivf_file_reader_unittest.cc @@ -9,11 +9,11 @@ */ #include "modules/video_coding/utility/ivf_file_reader.h" -#include "modules/video_coding/utility/ivf_file_writer.h" #include #include +#include "modules/video_coding/utility/ivf_file_writer.h" #include "test/gtest.h" #include "test/testsupport/file_utils.h" diff --git a/third_party/libwebrtc/modules/video_coding/utility/quality_scaler_unittest.cc b/third_party/libwebrtc/modules/video_coding/utility/quality_scaler_unittest.cc index c17159fb641c8..50410dd25bc7f 100644 --- a/third_party/libwebrtc/modules/video_coding/utility/quality_scaler_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/utility/quality_scaler_unittest.cc @@ -72,11 +72,10 @@ class QualityScalerTest : public ::testing::Test, : scoped_field_trial_(GetParam()), task_queue_("QualityScalerTestQueue"), handler_(std::make_unique()) { - task_queue_.SendTask( - [this] { - qs_ = std::unique_ptr(new QualityScalerUnderTest( - handler_.get(), VideoEncoder::QpThresholds(kLowQp, kHighQp))); - }); + task_queue_.SendTask([this] { + qs_ = std::unique_ptr(new QualityScalerUnderTest( + handler_.get(), VideoEncoder::QpThresholds(kLowQp, kHighQp))); + }); } ~QualityScalerTest() override { diff --git a/third_party/libwebrtc/modules/video_coding/video_codec_initializer.cc b/third_party/libwebrtc/modules/video_coding/video_codec_initializer.cc index 67a335d63b4e8..43fab8c4328a9 100644 --- a/third_party/libwebrtc/modules/video_coding/video_codec_initializer.cc +++ b/third_party/libwebrtc/modules/video_coding/video_codec_initializer.cc @@ -213,7 +213,7 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( case kVideoCodecVP9: { // When the SvcRateAllocator is used, "active" is controlled by // `SpatialLayer::active` instead. - if (video_codec.IsSinglecastOrAllNonFirstLayersInactive()) { + if (video_codec.numberOfSimulcastStreams <= 1) { video_codec.simulcastStream[0].active = codec_active; } @@ -242,7 +242,7 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( if (spatial_layers.empty()) break; // Use codec bitrate limits if spatial layering is not requested. - if (config.simulcast_layers.size() <= 1 && + if (video_codec.numberOfSimulcastStreams <= 1 && ScalabilityModeToNumSpatialLayers(*scalability_mode) == 1) { spatial_layers.back().minBitrate = video_codec.minBitrate; spatial_layers.back().targetBitrate = video_codec.maxBitrate; diff --git a/third_party/libwebrtc/modules/video_coding/video_codec_initializer_unittest.cc b/third_party/libwebrtc/modules/video_coding/video_codec_initializer_unittest.cc index b9d8465aa8dea..b0edab60040ec 100644 --- a/third_party/libwebrtc/modules/video_coding/video_codec_initializer_unittest.cc +++ b/third_party/libwebrtc/modules/video_coding/video_codec_initializer_unittest.cc @@ -589,11 +589,17 @@ TEST_F(VideoCodecInitializerTest, Vp9SingleSpatialLayerBitratesAreConsistent) { EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec)); EXPECT_EQ(1u, codec.VP9()->numberOfSpatialLayers); + // Target is consistent with min and max (min <= target <= max). EXPECT_GE(codec.spatialLayers[0].targetBitrate, codec.spatialLayers[0].minBitrate); EXPECT_LE(codec.spatialLayers[0].targetBitrate, codec.spatialLayers[0].maxBitrate); - EXPECT_LT(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000); + // In the single spatial layer case, the spatial layer bitrates are copied + // from the codec's bitrate which is the sum if VideoStream bitrates. In this + // case we only have a single VideoStream using default values. + EXPECT_EQ(codec.spatialLayers[0].minBitrate, kDefaultMinBitrateBps / 1000); + EXPECT_EQ(codec.spatialLayers[0].targetBitrate, kDefaultMaxBitrateBps / 1000); + EXPECT_EQ(codec.spatialLayers[0].maxBitrate, kDefaultMaxBitrateBps / 1000); } TEST_F(VideoCodecInitializerTest, Vp9TwoSpatialLayersBitratesAreConsistent) { diff --git a/third_party/libwebrtc/modules/video_coding/video_coding_impl.h b/third_party/libwebrtc/modules/video_coding/video_coding_impl.h index cd32330f946d2..de1703327789a 100644 --- a/third_party/libwebrtc/modules/video_coding/video_coding_impl.h +++ b/third_party/libwebrtc/modules/video_coding/video_coding_impl.h @@ -20,9 +20,9 @@ #include "api/field_trials_view.h" #include "api/sequence_checker.h" #include "modules/video_coding/deprecated/frame_buffer.h" +#include "modules/video_coding/deprecated/jitter_buffer.h" #include "modules/video_coding/generic_decoder.h" #include "modules/video_coding/include/video_coding.h" -#include "modules/video_coding/jitter_buffer.h" #include "modules/video_coding/receiver.h" #include "modules/video_coding/timing/timing.h" #include "rtc_base/one_time_event.h" diff --git a/third_party/libwebrtc/modules/video_coding/video_receiver.cc b/third_party/libwebrtc/modules/video_coding/video_receiver.cc index bf2ef0b4aad59..0363fd2736c46 100644 --- a/third_party/libwebrtc/modules/video_coding/video_receiver.cc +++ b/third_party/libwebrtc/modules/video_coding/video_receiver.cc @@ -18,13 +18,13 @@ #include "api/video_codecs/video_codec.h" #include "api/video_codecs/video_decoder.h" #include "modules/video_coding/decoder_database.h" +#include "modules/video_coding/deprecated/jitter_buffer.h" #include "modules/video_coding/deprecated/packet.h" #include "modules/video_coding/encoded_frame.h" #include "modules/video_coding/generic_decoder.h" #include "modules/video_coding/include/video_coding.h" #include "modules/video_coding/include/video_coding_defines.h" #include "modules/video_coding/internal_defines.h" -#include "modules/video_coding/jitter_buffer.h" #include "modules/video_coding/media_opt_util.h" #include "modules/video_coding/receiver.h" #include "modules/video_coding/timing/timing.h" diff --git a/third_party/libwebrtc/moz-patch-stack/0001.patch b/third_party/libwebrtc/moz-patch-stack/0001.patch index b0d4580a951cb..771ffabb2398b 100644 --- a/third_party/libwebrtc/moz-patch-stack/0001.patch +++ b/third_party/libwebrtc/moz-patch-stack/0001.patch @@ -207,9 +207,9 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/26eee332d844bd3f9 .../linux/x11/screen_capturer_x11.cc | 2 +- .../linux/x11/window_capturer_x11.cc | 12 +- .../linux/x11/window_capturer_x11.h | 4 + - .../desktop_capture/linux/x11/x_error_trap.cc | 70 ++++--- + .../desktop_capture/linux/x11/x_error_trap.cc | 68 +++--- .../desktop_capture/linux/x11/x_error_trap.h | 29 ++- - .../mouse_cursor_monitor_win.cc | 7 +- + .../mouse_cursor_monitor_win.cc | 4 + .../win/screen_capture_utils.cc | 3 +- .../win/screen_capturer_win_gdi.cc | 1 + .../win/screen_capturer_win_magnifier.cc | 16 +- @@ -236,7 +236,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/26eee332d844bd3f9 modules/video_coding/generic_decoder.cc | 5 +- test/fuzzers/rtp_packet_fuzzer.cc | 5 + test/vcm_capturer.cc | 2 +- - 45 files changed, 652 insertions(+), 134 deletions(-) + 45 files changed, 649 insertions(+), 132 deletions(-) diff --git a/api/rtp_headers.cc b/api/rtp_headers.cc index 0573e54684..40d4690397 100644 @@ -289,10 +289,10 @@ index 5d4d4190d5..9868365f24 100644 struct RTC_EXPORT RTPHeader { RTPHeader(); diff --git a/api/rtp_parameters.cc b/api/rtp_parameters.cc -index c48b8da02c..c1d12e5d8d 100644 +index 54132bcdbb..cf8b3ad3dc 100644 --- a/api/rtp_parameters.cc +++ b/api/rtp_parameters.cc -@@ -148,7 +148,8 @@ bool RtpExtension::IsSupportedForAudio(absl::string_view uri) { +@@ -151,7 +151,8 @@ bool RtpExtension::IsSupportedForAudio(absl::string_view uri) { uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri || uri == webrtc::RtpExtension::kMidUri || uri == webrtc::RtpExtension::kRidUri || @@ -303,7 +303,7 @@ index c48b8da02c..c1d12e5d8d 100644 bool RtpExtension::IsSupportedForVideo(absl::string_view uri) { diff --git a/call/BUILD.gn b/call/BUILD.gn -index f4c3295ff5..0e52e8fb3f 100644 +index c40cfcf28e..63a3a2d53d 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -20,6 +20,7 @@ rtc_library("call_interfaces") { @@ -757,25 +757,22 @@ index ac591c272e..cfd29eca66 100644 rtc::scoped_refptr x_display_; diff --git a/modules/desktop_capture/linux/x11/x_error_trap.cc b/modules/desktop_capture/linux/x11/x_error_trap.cc -index 94e3a03c73..3314dd286c 100644 +index 24c2065111..3314dd286c 100644 --- a/modules/desktop_capture/linux/x11/x_error_trap.cc +++ b/modules/desktop_capture/linux/x11/x_error_trap.cc -@@ -10,50 +10,60 @@ +@@ -12,48 +12,58 @@ - #include "modules/desktop_capture/linux/x11/x_error_trap.h" - --#include -- #include --#include "rtc_base/checks.h" -- --namespace webrtc { +-#include +#include --namespace { -+#include "rtc_base/checks.h" + #include "rtc_base/checks.h" +-namespace webrtc { +- +-namespace { +- -static int g_last_xserver_error_code = 0; -static std::atomic g_display_for_error_handler = nullptr; @@ -906,7 +903,7 @@ index 1f21ab969c..df7e86bf03 100644 } // namespace webrtc diff --git a/modules/desktop_capture/mouse_cursor_monitor_win.cc b/modules/desktop_capture/mouse_cursor_monitor_win.cc -index c892d59955..18ef43eeb4 100644 +index c892d59955..aa2347423c 100644 --- a/modules/desktop_capture/mouse_cursor_monitor_win.cc +++ b/modules/desktop_capture/mouse_cursor_monitor_win.cc @@ -88,6 +88,7 @@ MouseCursorMonitorWin::~MouseCursorMonitorWin() { @@ -926,17 +923,7 @@ index c892d59955..18ef43eeb4 100644 RTC_DCHECK(callback_); CURSORINFO cursor_info; -@@ -107,7 +110,8 @@ void MouseCursorMonitorWin::Capture() { - } - - if (!IsSameCursorShape(cursor_info, last_cursor_)) { -- if (cursor_info.flags == CURSOR_SUPPRESSED) { -+ // Mozilla - CURSOR_SUPPRESSED is win8 and above; so we seem not to be able to see the symbol -+ if (cursor_info.flags != CURSOR_SHOWING) { - // The cursor is intentionally hidden now, send an empty bitmap. - last_cursor_ = cursor_info; - callback_->OnMouseCursor(new MouseCursor( -@@ -168,6 +172,7 @@ void MouseCursorMonitorWin::Capture() { +@@ -168,6 +171,7 @@ void MouseCursorMonitorWin::Capture() { } DesktopRect MouseCursorMonitorWin::GetScreenRect() { @@ -1937,10 +1924,10 @@ index 60afb986de..0e10a8fa3a 100644 } diff --git a/test/vcm_capturer.cc b/test/vcm_capturer.cc -index a037f9eff6..e02fc722b2 100644 +index 0a9226ef6f..620c1c02f3 100644 --- a/test/vcm_capturer.cc +++ b/test/vcm_capturer.cc -@@ -81,7 +81,7 @@ void VcmCapturer::Destroy() { +@@ -83,7 +83,7 @@ void VcmCapturer::Destroy() { return; vcm_->StopCapture(); diff --git a/third_party/libwebrtc/moz-patch-stack/0003.patch b/third_party/libwebrtc/moz-patch-stack/0003.patch index d80851746b285..0790cb1ee52bf 100644 --- a/third_party/libwebrtc/moz-patch-stack/0003.patch +++ b/third_party/libwebrtc/moz-patch-stack/0003.patch @@ -37,7 +37,7 @@ index f787b65604..a15321ad48 100644 if (base.length() && base.back() != sep) { diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc -index 65d50594b6..909cc744fc 100644 +index 61a3c667ba..c28dbe3a10 100644 --- a/rtc_base/logging.cc +++ b/rtc_base/logging.cc @@ -54,6 +54,15 @@ static const int kMaxLogLineSize = 1024 - 60; diff --git a/third_party/libwebrtc/moz-patch-stack/0004.patch b/third_party/libwebrtc/moz-patch-stack/0004.patch index 84de59eb91ee8..728b7b98ac857 100644 --- a/third_party/libwebrtc/moz-patch-stack/0004.patch +++ b/third_party/libwebrtc/moz-patch-stack/0004.patch @@ -9,7 +9,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/3d5503acf9a4b22e0 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc -index 909cc744fc..ef517f1df8 100644 +index c28dbe3a10..eac04fdc06 100644 --- a/rtc_base/logging.cc +++ b/rtc_base/logging.cc @@ -265,8 +265,8 @@ void LogMessage::LogTimestamps(bool on) { @@ -22,7 +22,7 @@ index 909cc744fc..ef517f1df8 100644 UpdateMinLogSeverity(); } -@@ -451,6 +451,9 @@ void LogMessage::OutputToDebug(const LogLineRef& log_line) { +@@ -450,6 +450,9 @@ void LogMessage::OutputToDebug(const LogLineRef& log_line) { // static bool LogMessage::IsNoop(LoggingSeverity severity) { diff --git a/third_party/libwebrtc/moz-patch-stack/0007.patch b/third_party/libwebrtc/moz-patch-stack/0007.patch index e1743a0bd46fc..bcb7953b2ef13 100644 --- a/third_party/libwebrtc/moz-patch-stack/0007.patch +++ b/third_party/libwebrtc/moz-patch-stack/0007.patch @@ -30,7 +30,7 @@ index 1918354009..b23350e6d1 100644 // single 'timing frame'. absl::optional timing_frame_info; diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc -index 69fd1f6f07..61df619546 100644 +index 5f53c5823c..77029ffcd9 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -392,6 +392,13 @@ RTCPReceiver::ConsumeReceivedXrReferenceTimeInfo() { @@ -63,10 +63,10 @@ index 567b5b36f3..0ec14bc8c6 100644 int32_t RTT(uint32_t remote_ssrc, int64_t* last_rtt_ms, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index c3e5e93223..fbbebceb8d 100644 +index 75fee87deb..7fd56600c7 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -507,6 +507,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( +@@ -506,6 +506,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( } // Received RTCP report. @@ -93,10 +93,10 @@ index c8e90c25b0..38e20261c5 100644 // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. // Within this list, the ReportBlockData::RTCPReportBlock::source_ssrc(), diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -index bbcd5d83b1..cb90ca792f 100644 +index d33ef86169..12c2ee2317 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -@@ -487,6 +487,11 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( +@@ -486,6 +486,11 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( } // Received RTCP report. @@ -123,10 +123,10 @@ index e6da54929b..79833288de 100644 // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. // Within this list, the ReportBlockData::RTCPReportBlock::source_ssrc(), diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -index d49051be63..6d37898442 100644 +index 66a29c9ddd..7f329ab1a7 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -@@ -393,6 +393,10 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { +@@ -392,6 +392,10 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { StreamDataCounters* rtp_counters, StreamDataCounters* rtx_counters) const = 0; diff --git a/third_party/libwebrtc/moz-patch-stack/0008.patch b/third_party/libwebrtc/moz-patch-stack/0008.patch index ecf6b1acb3867..81197e0d3777a 100644 --- a/third_party/libwebrtc/moz-patch-stack/0008.patch +++ b/third_party/libwebrtc/moz-patch-stack/0008.patch @@ -33,7 +33,7 @@ index b23350e6d1..767c3c64fd 100644 // Timing frame info: all important timestamps for a full lifetime of a // single 'timing frame'. diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc -index 61df619546..a8e99cbd14 100644 +index 77029ffcd9..3210e7a9e3 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -393,10 +393,12 @@ RTCPReceiver::ConsumeReceivedXrReferenceTimeInfo() { @@ -65,10 +65,10 @@ index 0ec14bc8c6..68bb16bd8b 100644 // Get rtt. int32_t RTT(uint32_t remote_ssrc, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index fbbebceb8d..f5c1f96df4 100644 +index 7fd56600c7..ac3773fef7 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -508,8 +508,10 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( +@@ -507,8 +507,10 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( // Received RTCP report. void ModuleRtpRtcpImpl::RemoteRTCPSenderInfo(uint32_t* packet_count, @@ -96,10 +96,10 @@ index 38e20261c5..d9891166d6 100644 // A snapshot of the most recent Report Block with additional data of // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -index cb90ca792f..573dc93679 100644 +index 12c2ee2317..9407b79b52 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -@@ -488,8 +488,10 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( +@@ -487,8 +487,10 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( // Received RTCP report. void ModuleRtpRtcpImpl2::RemoteRTCPSenderInfo(uint32_t* packet_count, @@ -127,10 +127,10 @@ index 79833288de..00d01df6ea 100644 // A snapshot of the most recent Report Block with additional data of // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -index 6d37898442..3be50835a4 100644 +index 7f329ab1a7..b791a5c88d 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -@@ -394,9 +394,10 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { +@@ -393,9 +393,10 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { StreamDataCounters* rtx_counters) const = 0; diff --git a/third_party/libwebrtc/moz-patch-stack/0009.patch b/third_party/libwebrtc/moz-patch-stack/0009.patch index 9d2bd64f02526..127715fd7b729 100644 --- a/third_party/libwebrtc/moz-patch-stack/0009.patch +++ b/third_party/libwebrtc/moz-patch-stack/0009.patch @@ -13,10 +13,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/02c038eca65c1218b create mode 100644 modules/desktop_capture/screen_capturer_mac.mm diff --git a/modules/desktop_capture/mac/screen_capturer_mac.h b/modules/desktop_capture/mac/screen_capturer_mac.h -index d9a5966efa..7be05cc639 100644 +index 7e38b5bd08..e4a2cc2fc9 100644 --- a/modules/desktop_capture/mac/screen_capturer_mac.h +++ b/modules/desktop_capture/mac/screen_capturer_mac.h -@@ -114,6 +114,13 @@ class ScreenCapturerMac final : public DesktopCapturer { +@@ -113,6 +113,13 @@ class ScreenCapturerMac final : public DesktopCapturer { // Start, CaptureFrame and destructor have to called in the same thread. SequenceChecker thread_checker_; @@ -31,10 +31,10 @@ index d9a5966efa..7be05cc639 100644 } // namespace webrtc diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm -index 634849122e..115f6440b1 100644 +index 8f0c68d48b..8b9af35193 100644 --- a/modules/desktop_capture/mac/screen_capturer_mac.mm +++ b/modules/desktop_capture/mac/screen_capturer_mac.mm -@@ -182,6 +182,7 @@ void ScreenCapturerMac::Start(Callback* callback) { +@@ -263,6 +263,7 @@ void ScreenCapturerMac::Start(Callback* callback) { "webrtc", "ScreenCapturermac::Start", "target display id ", current_display_); callback_ = callback; @@ -42,7 +42,7 @@ index 634849122e..115f6440b1 100644 // Start and operate CGDisplayStream handler all from capture thread. if (!RegisterRefreshAndMoveHandlers()) { RTC_LOG(LS_ERROR) << "Failed to register refresh and move handlers."; -@@ -202,7 +203,8 @@ void ScreenCapturerMac::CaptureFrame() { +@@ -283,7 +284,8 @@ void ScreenCapturerMac::CaptureFrame() { } MacDesktopConfiguration new_config = desktop_config_monitor_->desktop_configuration(); diff --git a/third_party/libwebrtc/moz-patch-stack/0010.patch b/third_party/libwebrtc/moz-patch-stack/0010.patch index 13103c1ab42bf..138f5c517f087 100644 --- a/third_party/libwebrtc/moz-patch-stack/0010.patch +++ b/third_party/libwebrtc/moz-patch-stack/0010.patch @@ -16,10 +16,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/9314046d89ebc0836 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm -index 115f6440b1..cad0c5b65b 100644 +index 8b9af35193..76fec13a39 100644 --- a/modules/desktop_capture/mac/screen_capturer_mac.mm +++ b/modules/desktop_capture/mac/screen_capturer_mac.mm -@@ -276,7 +276,8 @@ bool ScreenCapturerMac::GetSourceList(SourceList* screens) { +@@ -357,7 +357,8 @@ bool ScreenCapturerMac::GetSourceList(SourceList* screens) { for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin(); it != desktop_config_.displays.end(); ++it) { diff --git a/third_party/libwebrtc/moz-patch-stack/0020.patch b/third_party/libwebrtc/moz-patch-stack/0020.patch index 72b949b3c180f..07556a6b808db 100644 --- a/third_party/libwebrtc/moz-patch-stack/0020.patch +++ b/third_party/libwebrtc/moz-patch-stack/0020.patch @@ -14,7 +14,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/840c4edafa021eeac 2 files changed, 42 insertions(+) diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index fb8d55137f..8543dce746 100644 +index f9be3f83ef..8108d1176f 100644 --- a/modules/video_capture/windows/device_info_ds.cc +++ b/modules/video_capture/windows/device_info_ds.cc @@ -20,6 +20,29 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/0021.patch b/third_party/libwebrtc/moz-patch-stack/0021.patch index d9fdd2cb9d50d..d935e8653cfb6 100644 --- a/third_party/libwebrtc/moz-patch-stack/0021.patch +++ b/third_party/libwebrtc/moz-patch-stack/0021.patch @@ -13,7 +13,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/1feec83ee6f92a35d 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index 8543dce746..96db60c968 100644 +index 8108d1176f..630071864b 100644 --- a/modules/video_capture/windows/device_info_ds.cc +++ b/modules/video_capture/windows/device_info_ds.cc @@ -20,6 +20,18 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/0023.patch b/third_party/libwebrtc/moz-patch-stack/0023.patch index 83497607c2fcc..f35361ad4d3dc 100644 --- a/third_party/libwebrtc/moz-patch-stack/0023.patch +++ b/third_party/libwebrtc/moz-patch-stack/0023.patch @@ -12,7 +12,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a5c23245837ebdd99 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index 96db60c968..3ab95837c0 100644 +index 630071864b..e1a16e979c 100644 --- a/modules/video_capture/windows/device_info_ds.cc +++ b/modules/video_capture/windows/device_info_ds.cc @@ -20,7 +20,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/0034.patch b/third_party/libwebrtc/moz-patch-stack/0034.patch index d549a81c6ead0..cdb253eab11c7 100644 --- a/third_party/libwebrtc/moz-patch-stack/0034.patch +++ b/third_party/libwebrtc/moz-patch-stack/0034.patch @@ -7,8 +7,8 @@ Subject: (fix) reconcile github with what was actually committed in .../signal_processing/filter_ar_fast_q12.c | 2 +- .../linux/wayland/base_capturer_pipewire.cc | 11 +- .../video_capture/linux/device_info_v4l2.cc | 1 + - rtc_base/trace_event.h | 1025 +---------------- - 4 files changed, 15 insertions(+), 1024 deletions(-) + rtc_base/trace_event.h | 1055 +---------------- + 4 files changed, 15 insertions(+), 1054 deletions(-) diff --git a/common_audio/signal_processing/filter_ar_fast_q12.c b/common_audio/signal_processing/filter_ar_fast_q12.c index 8b8bdb1af5..9010f1ce82 100644 @@ -65,10 +65,10 @@ index d506f3a448..e8abcdda78 100644 } diff --git a/rtc_base/trace_event.h b/rtc_base/trace_event.h -index e9a5c4c6f2..b34df0c93f 100644 +index 6689bc0c37..b34df0c93f 100644 --- a/rtc_base/trace_event.h +++ b/rtc_base/trace_event.h -@@ -1,1022 +1,3 @@ +@@ -1,1052 +1,3 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file under third_party_mods/chromium or at: @@ -92,13 +92,13 @@ index e9a5c4c6f2..b34df0c93f 100644 -#endif - -// Type values for identifying types in the TraceValue union. --#define TRACE_VALUE_TYPE_BOOL (static_cast(1)) --#define TRACE_VALUE_TYPE_UINT (static_cast(2)) --#define TRACE_VALUE_TYPE_INT (static_cast(3)) --#define TRACE_VALUE_TYPE_DOUBLE (static_cast(4)) --#define TRACE_VALUE_TYPE_POINTER (static_cast(5)) --#define TRACE_VALUE_TYPE_STRING (static_cast(6)) --#define TRACE_VALUE_TYPE_COPY_STRING (static_cast(7)) +-#define TRACE_VALUE_TYPE_BOOL (static_cast(1)) +-#define TRACE_VALUE_TYPE_UINT (static_cast(2)) +-#define TRACE_VALUE_TYPE_INT (static_cast(3)) +-#define TRACE_VALUE_TYPE_DOUBLE (static_cast(4)) +-#define TRACE_VALUE_TYPE_POINTER (static_cast(5)) +-#define TRACE_VALUE_TYPE_STRING (static_cast(6)) +-#define TRACE_VALUE_TYPE_COPY_STRING (static_cast(7)) - -#if RTC_TRACE_EVENTS_ENABLED - @@ -232,7 +232,7 @@ index e9a5c4c6f2..b34df0c93f 100644 -// By default, const char* argument values are assumed to have long-lived scope -// and will not be copied. Use this macro to force a const char* to be copied. -#define TRACE_STR_COPY(str) \ -- webrtc::trace_event_internal::TraceStringWithCopy(str) +- webrtc::trace_event_internal::TraceStringWithCopy(str) - -// This will mark the trace event as disabled by default. The user will need -// to explicitly enable the event. @@ -241,7 +241,7 @@ index e9a5c4c6f2..b34df0c93f 100644 -// By default, uint64 ID argument values are not mangled with the Process ID in -// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling. -#define TRACE_ID_MANGLE(id) \ -- webrtc::trace_event_internal::TraceID::ForceMangle(id) +- webrtc::trace_event_internal::TraceID::ForceMangle(id) - -// Records a pair of begin and end events called "name" for the current -// scope, with 0, 1 or 2 associated arguments. If the category is not @@ -249,126 +249,126 @@ index e9a5c4c6f2..b34df0c93f 100644 -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. -#define TRACE_EVENT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name) +- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name) -#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val) +- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val) -#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) +- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \ +- arg2_name, arg2_val) - -// Records a single event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this -// does nothing. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. --#define TRACE_EVENT_INSTANT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_INSTANT0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_INSTANT0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +-#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ +- arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_INSTANT0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) -#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ +- arg2_name, arg2_val) - -// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this -// does nothing. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. --#define TRACE_EVENT_BEGIN0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_BEGIN0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_BEGIN0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +-#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ +- arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_BEGIN0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) --#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +-#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ +- arg2_name, arg2_val) - -// Records a single END event for "name" immediately. If the category -// is not enabled, then this does nothing. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. --#define TRACE_EVENT_END0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ -- arg2_name, arg2_val) --#define TRACE_EVENT_COPY_END0(category, name) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_END0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) +-#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ +- arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_END0(category, name) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) --#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ -- category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ -- arg2_name, arg2_val) +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) +-#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category, name, \ +- TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ +- arg2_name, arg2_val) - -// Records the value of a counter called "name" immediately. Value -// must be representable as a 32 bit integer. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. --#define TRACE_COUNTER1(category, name, value) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_NONE, \ -- "value", static_cast(value)) --#define TRACE_COPY_COUNTER1(category, name, value) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_COPY, \ -- "value", static_cast(value)) +-#define TRACE_COUNTER1(category, name, value) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- TRACE_EVENT_FLAG_NONE, "value", \ +- static_cast(value)) +-#define TRACE_COPY_COUNTER1(category, name, value) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- TRACE_EVENT_FLAG_COPY, "value", \ +- static_cast(value)) - -// Records the values of a multi-parted counter called "name" immediately. -// The UI will treat value1 and value2 as parts of a whole, displaying their -// values as a stacked-bar chart. -// - category and name strings must have application lifetime (statics or -// literals). They may not include " chars. --#define TRACE_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_NONE, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) --#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, TRACE_EVENT_FLAG_COPY, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) +-#define TRACE_COUNTER2(category, name, value1_name, value1_val, value2_name, \ +- value2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- TRACE_EVENT_FLAG_NONE, value1_name, \ +- static_cast(value1_val), value2_name, \ +- static_cast(value2_val)) +-#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ +- value2_name, value2_val) \ +- INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- TRACE_EVENT_FLAG_COPY, value1_name, \ +- static_cast(value1_val), value2_name, \ +- static_cast(value2_val)) - -// Records the value of a counter called "name" immediately. Value -// must be representable as a 32 bit integer. @@ -378,14 +378,14 @@ index e9a5c4c6f2..b34df0c93f 100644 -// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits -// will be xored with a hash of the process ID so that the same pointer on -// two different processes will not collide. --#define TRACE_COUNTER_ID1(category, name, id, value) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- "value", static_cast(value)) --#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- "value", static_cast(value)) +-#define TRACE_COUNTER_ID1(category, name, id, value) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- id, TRACE_EVENT_FLAG_NONE, "value", \ +- static_cast(value)) +-#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- id, TRACE_EVENT_FLAG_COPY, "value", \ +- static_cast(value)) - -// Records the values of a multi-parted counter called "name" immediately. -// The UI will treat value1 and value2 as parts of a whole, displaying their @@ -396,19 +396,18 @@ index e9a5c4c6f2..b34df0c93f 100644 -// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits -// will be xored with a hash of the process ID so that the same pointer on -// two different processes will not collide. --#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) --#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- value1_name, static_cast(value1_val), \ -- value2_name, static_cast(value2_val)) -- +-#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ +- value2_name, value2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- id, TRACE_EVENT_FLAG_NONE, value1_name, \ +- static_cast(value1_val), value2_name, \ +- static_cast(value2_val)) +-#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ +- value2_name, value2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category, name, \ +- id, TRACE_EVENT_FLAG_COPY, value1_name, \ +- static_cast(value1_val), value2_name, \ +- static_cast(value2_val)) - -// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this @@ -427,78 +426,80 @@ index e9a5c4c6f2..b34df0c93f 100644 -// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that -// operation must use the same `name` and `id`. Each event can have its own -// args. --#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val, arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY) -#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val) -#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val, arg2_name, arg2_val) - -// Records a single ASYNC_STEP event for `step` immediately. If the category -// is not enabled, then this does nothing. The `name` and `id` must match the -// ASYNC_BEGIN event above. The `step` param identifies this step within the -// async event. This should be called at the beginning of the next phase of an -// asynchronous operation. --#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) --#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) --#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ -- arg1_name, arg1_val) +-#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, "step", \ +- step) +-#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, "step", \ +- step, arg1_name, arg1_val) +-#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, "step", \ +- step) +-#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, arg1_name, \ +- arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, "step", \ +- step, arg1_name, arg1_val) - -// Records a single ASYNC_END event for "name" immediately. If the category -// is not enabled, then this does nothing. --#define TRACE_EVENT_ASYNC_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) -- +-#define TRACE_EVENT_ASYNC_END0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val, arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val, arg2_name, arg2_val) - -// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2 -// associated arguments. If the category is not enabled, then this @@ -519,78 +520,80 @@ index e9a5c4c6f2..b34df0c93f 100644 -// macros. When the operation completes, call FLOW_END. An async operation can -// span threads and processes, but all events in that operation must use the -// same `name` and `id`. Each event can have its own args. --#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) +-#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val, arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val, arg2_name, arg2_val) - -// Records a single FLOW_STEP event for `step` immediately. If the category -// is not enabled, then this does nothing. The `name` and `id` must match the -// FLOW_BEGIN event above. The `step` param identifies this step within the -// async event. This should be called at the beginning of the next phase of an -// asynchronous operation. --#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) --#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) --#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ -- arg1_name, arg1_val) +-#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, "step", \ +- step) +-#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_NONE, "step", \ +- step, arg1_name, arg1_val) +-#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, "step", \ +- step) +-#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, arg1_name, \ +- arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, category, \ +- name, id, TRACE_EVENT_FLAG_COPY, "step", \ +- step, arg1_name, arg1_val) - -// Records a single FLOW_END event for "name" immediately. If the category -// is not enabled, then this does nothing. --#define TRACE_EVENT_FLOW_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE) --#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) --#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_NONE, \ -- arg1_name, arg1_val, arg2_name, arg2_val) --#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY) --#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val) --#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) \ -- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \ -- category, name, id, TRACE_EVENT_FLAG_COPY, \ -- arg1_name, arg1_val, arg2_name, arg2_val) -- +-#define TRACE_EVENT_FLOW_END0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_NONE) +-#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_NONE, arg1_name, \ +- arg1_val, arg2_name, arg2_val) +-#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_COPY) +-#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val) +-#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \ +- arg2_name, arg2_val) \ +- INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, category, name, \ +- id, TRACE_EVENT_FLAG_COPY, arg1_name, \ +- arg1_val, arg2_name, arg2_val) - -//////////////////////////////////////////////////////////////////////////////// -// Implementation specific tracing API definitions. @@ -606,7 +609,7 @@ index e9a5c4c6f2..b34df0c93f 100644 -// const unsigned char* -// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) -#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ -- webrtc::EventTracer::GetCategoryEnabled +- webrtc::EventTracer::GetCategoryEnabled - -// Add a trace event to the platform tracing system. -// void TRACE_EVENT_API_ADD_TRACE_EVENT( @@ -626,12 +629,10 @@ index e9a5c4c6f2..b34df0c93f 100644 -// Implementation detail: trace event macros create temporary variables -// to keep instrumentation overhead low. These macros give each temporary -// variable a unique name based on the line number to prevent name collissions. --#define INTERNAL_TRACE_EVENT_UID3(a,b) \ -- trace_event_unique_##a##b --#define INTERNAL_TRACE_EVENT_UID2(a,b) \ -- INTERNAL_TRACE_EVENT_UID3(a,b) +-#define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b +-#define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b) -#define INTERNAL_TRACE_EVENT_UID(name_prefix) \ -- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) +- INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) - -#if WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS -#define INTERNAL_TRACE_EVENT_INFO_TYPE const unsigned char* @@ -640,55 +641,53 @@ index e9a5c4c6f2..b34df0c93f 100644 -#endif // WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS - -// Implementation detail: internal macro to create static category. --#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \ -- INTERNAL_TRACE_EVENT_INFO_TYPE INTERNAL_TRACE_EVENT_UID(catstatic) = \ -- TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); +-#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \ +- INTERNAL_TRACE_EVENT_INFO_TYPE INTERNAL_TRACE_EVENT_UID(catstatic) = \ +- TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); - -// Implementation detail: internal macro to create static category and add -// event if the category is enabled. --#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \ -- do { \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ -- webrtc::trace_event_internal::AddTraceEvent( \ -- phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \ -- webrtc::trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \ -- } \ -- } while (0) +-#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \ +- do { \ +- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ +- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ +- webrtc::trace_event_internal::AddTraceEvent( \ +- phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \ +- webrtc::trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \ +- } \ +- } while (0) - -// Implementation detail: internal macro to create static category and add begin -// event if the category is enabled. Also adds the end event when the scope -// ends. --#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- webrtc::trace_event_internal::TraceEndOnScopeClose \ -- INTERNAL_TRACE_EVENT_UID(profileScope); \ -- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ -- webrtc::trace_event_internal::AddTraceEvent( \ -- TRACE_EVENT_PHASE_BEGIN, \ -- INTERNAL_TRACE_EVENT_UID(catstatic), \ -- name, webrtc::trace_event_internal::kNoEventId, \ -- TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ -- INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ -- INTERNAL_TRACE_EVENT_UID(catstatic), name); \ -- } +-#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \ +- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ +- webrtc::trace_event_internal::TraceEndOnScopeClose INTERNAL_TRACE_EVENT_UID( \ +- profileScope); \ +- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ +- webrtc::trace_event_internal::AddTraceEvent( \ +- TRACE_EVENT_PHASE_BEGIN, INTERNAL_TRACE_EVENT_UID(catstatic), name, \ +- webrtc::trace_event_internal::kNoEventId, TRACE_EVENT_FLAG_NONE, \ +- ##__VA_ARGS__); \ +- INTERNAL_TRACE_EVENT_UID(profileScope) \ +- .Initialize(INTERNAL_TRACE_EVENT_UID(catstatic), name); \ +- } - -// Implementation detail: internal macro to create static category and add -// event if the category is enabled. -#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \ -- ...) \ -- do { \ -- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ -- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ -- unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ -- webrtc::trace_event_internal::TraceID trace_event_trace_id( \ -- id, &trace_event_flags); \ -- webrtc::trace_event_internal::AddTraceEvent( \ -- phase, INTERNAL_TRACE_EVENT_UID(catstatic), \ -- name, trace_event_trace_id.data(), trace_event_flags, \ -- ##__VA_ARGS__); \ -- } \ -- } while (0) +- ...) \ +- do { \ +- INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ +- if (*INTERNAL_TRACE_EVENT_UID(catstatic)) { \ +- unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \ +- webrtc::trace_event_internal::TraceID trace_event_trace_id( \ +- id, &trace_event_flags); \ +- webrtc::trace_event_internal::AddTraceEvent( \ +- phase, INTERNAL_TRACE_EVENT_UID(catstatic), name, \ +- trace_event_trace_id.data(), trace_event_flags, ##__VA_ARGS__); \ +- } \ +- } while (0) - -// Notes regarding the following definitions: -// New values can be added and propagated to third party libraries, but existing @@ -696,23 +695,23 @@ index e9a5c4c6f2..b34df0c93f 100644 -// definitions. - -// Phase indicates the nature of an event entry. E.g. part of a begin/end pair. --#define TRACE_EVENT_PHASE_BEGIN ('B') --#define TRACE_EVENT_PHASE_END ('E') --#define TRACE_EVENT_PHASE_INSTANT ('I') +-#define TRACE_EVENT_PHASE_BEGIN ('B') +-#define TRACE_EVENT_PHASE_END ('E') +-#define TRACE_EVENT_PHASE_INSTANT ('I') -#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S') --#define TRACE_EVENT_PHASE_ASYNC_STEP ('T') --#define TRACE_EVENT_PHASE_ASYNC_END ('F') +-#define TRACE_EVENT_PHASE_ASYNC_STEP ('T') +-#define TRACE_EVENT_PHASE_ASYNC_END ('F') -#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s') --#define TRACE_EVENT_PHASE_FLOW_STEP ('t') --#define TRACE_EVENT_PHASE_FLOW_END ('f') +-#define TRACE_EVENT_PHASE_FLOW_STEP ('t') +-#define TRACE_EVENT_PHASE_FLOW_END ('f') -#define TRACE_EVENT_PHASE_METADATA ('M') --#define TRACE_EVENT_PHASE_COUNTER ('C') +-#define TRACE_EVENT_PHASE_COUNTER ('C') - -// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. --#define TRACE_EVENT_FLAG_NONE (static_cast(0)) --#define TRACE_EVENT_FLAG_COPY (static_cast(1 << 0)) --#define TRACE_EVENT_FLAG_HAS_ID (static_cast(1 << 1)) --#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast(1 << 2)) +-#define TRACE_EVENT_FLAG_NONE (static_cast(0)) +-#define TRACE_EVENT_FLAG_COPY (static_cast(1 << 0)) +-#define TRACE_EVENT_FLAG_HAS_ID (static_cast(1 << 1)) +-#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast(1 << 2)) - -namespace webrtc { -namespace trace_event_internal { @@ -728,57 +727,71 @@ index e9a5c4c6f2..b34df0c93f 100644 -class TraceID { - public: - class ForceMangle { -- public: -- explicit ForceMangle(unsigned long long id) : data_(id) {} -- explicit ForceMangle(unsigned long id) : data_(id) {} -- explicit ForceMangle(unsigned int id) : data_(id) {} -- explicit ForceMangle(unsigned short id) : data_(id) {} -- explicit ForceMangle(unsigned char id) : data_(id) {} -- explicit ForceMangle(long long id) -- : data_(static_cast(id)) {} -- explicit ForceMangle(long id) -- : data_(static_cast(id)) {} -- explicit ForceMangle(int id) -- : data_(static_cast(id)) {} -- explicit ForceMangle(short id) -- : data_(static_cast(id)) {} -- explicit ForceMangle(signed char id) -- : data_(static_cast(id)) {} -- -- unsigned long long data() const { return data_; } -- -- private: -- unsigned long long data_; +- public: +- explicit ForceMangle(unsigned long long id) : data_(id) {} +- explicit ForceMangle(unsigned long id) : data_(id) {} +- explicit ForceMangle(unsigned int id) : data_(id) {} +- explicit ForceMangle(unsigned short id) : data_(id) {} +- explicit ForceMangle(unsigned char id) : data_(id) {} +- explicit ForceMangle(long long id) +- : data_(static_cast(id)) {} +- explicit ForceMangle(long id) +- : data_(static_cast(id)) {} +- explicit ForceMangle(int id) : data_(static_cast(id)) {} +- explicit ForceMangle(short id) +- : data_(static_cast(id)) {} +- explicit ForceMangle(signed char id) +- : data_(static_cast(id)) {} +- +- unsigned long long data() const { return data_; } +- +- private: +- unsigned long long data_; - }; - - explicit TraceID(const void* id, unsigned char* flags) -- : data_(static_cast( -- reinterpret_cast(id))) { +- : data_( +- static_cast(reinterpret_cast(id))) { - *flags |= TRACE_EVENT_FLAG_MANGLE_ID; - } - explicit TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) { - *flags |= TRACE_EVENT_FLAG_MANGLE_ID; - } -- explicit TraceID(unsigned long long id, unsigned char* flags) -- : data_(id) { (void)flags; } -- explicit TraceID(unsigned long id, unsigned char* flags) -- : data_(id) { (void)flags; } -- explicit TraceID(unsigned int id, unsigned char* flags) -- : data_(id) { (void)flags; } -- explicit TraceID(unsigned short id, unsigned char* flags) -- : data_(id) { (void)flags; } -- explicit TraceID(unsigned char id, unsigned char* flags) -- : data_(id) { (void)flags; } +- explicit TraceID(unsigned long long id, unsigned char* flags) : data_(id) { +- (void)flags; +- } +- explicit TraceID(unsigned long id, unsigned char* flags) : data_(id) { +- (void)flags; +- } +- explicit TraceID(unsigned int id, unsigned char* flags) : data_(id) { +- (void)flags; +- } +- explicit TraceID(unsigned short id, unsigned char* flags) : data_(id) { +- (void)flags; +- } +- explicit TraceID(unsigned char id, unsigned char* flags) : data_(id) { +- (void)flags; +- } - explicit TraceID(long long id, unsigned char* flags) -- : data_(static_cast(id)) { (void)flags; } +- : data_(static_cast(id)) { +- (void)flags; +- } - explicit TraceID(long id, unsigned char* flags) -- : data_(static_cast(id)) { (void)flags; } +- : data_(static_cast(id)) { +- (void)flags; +- } - explicit TraceID(int id, unsigned char* flags) -- : data_(static_cast(id)) { (void)flags; } +- : data_(static_cast(id)) { +- (void)flags; +- } - explicit TraceID(short id, unsigned char* flags) -- : data_(static_cast(id)) { (void)flags; } +- : data_(static_cast(id)) { +- (void)flags; +- } - explicit TraceID(signed char id, unsigned char* flags) -- : data_(static_cast(id)) { (void)flags; } +- : data_(static_cast(id)) { +- (void)flags; +- } - - unsigned long long data() const { return data_; } - @@ -800,7 +813,8 @@ index e9a5c4c6f2..b34df0c93f 100644 -class TraceStringWithCopy { - public: - explicit TraceStringWithCopy(const char* str) : str_(str) {} -- operator const char* () const { return str_; } +- operator const char*() const { return str_; } +- - private: - const char* str_; -}; @@ -808,26 +822,22 @@ index e9a5c4c6f2..b34df0c93f 100644 -// Define SetTraceValue for each allowed type. It stores the type and -// value in the return arguments. This allows this API to avoid declaring any -// structures so that it is portable to third_party libraries. --#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \ -- union_member, \ -- value_type_id) \ -- static inline void SetTraceValue(actual_type arg, \ -- unsigned char* type, \ -- unsigned long long* value) { \ -- TraceValueUnion type_value; \ -- type_value.union_member = arg; \ -- *type = value_type_id; \ -- *value = type_value.as_uint; \ -- } +-#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member, \ +- value_type_id) \ +- static inline void SetTraceValue(actual_type arg, unsigned char* type, \ +- unsigned long long* value) { \ +- TraceValueUnion type_value; \ +- type_value.union_member = arg; \ +- *type = value_type_id; \ +- *value = type_value.as_uint; \ +- } -// Simpler form for int types that can be safely casted. --#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \ -- value_type_id) \ -- static inline void SetTraceValue(actual_type arg, \ -- unsigned char* type, \ -- unsigned long long* value) { \ -- *type = value_type_id; \ -- *value = static_cast(arg); \ -- } +-#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id) \ +- static inline void SetTraceValue(actual_type arg, unsigned char* type, \ +- unsigned long long* value) { \ +- *type = value_type_id; \ +- *value = static_cast(arg); \ +- } - -INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT) -INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT) @@ -841,11 +851,14 @@ index e9a5c4c6f2..b34df0c93f 100644 -INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) -INTERNAL_DECLARE_SET_TRACE_VALUE(bool, as_bool, TRACE_VALUE_TYPE_BOOL) -INTERNAL_DECLARE_SET_TRACE_VALUE(double, as_double, TRACE_VALUE_TYPE_DOUBLE) --INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, as_pointer, +-INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, +- as_pointer, - TRACE_VALUE_TYPE_POINTER) --INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, as_string, +-INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, +- as_string, - TRACE_VALUE_TYPE_STRING) --INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, as_string, +-INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, +- as_string, - TRACE_VALUE_TYPE_COPY_STRING) - -#undef INTERNAL_DECLARE_SET_TRACE_VALUE @@ -868,53 +881,49 @@ index e9a5c4c6f2..b34df0c93f 100644 -// these procedures. - -static inline void AddTraceEvent(char phase, -- const unsigned char* category_enabled, -- const char* name, -- unsigned long long id, -- unsigned char flags) { +- const unsigned char* category_enabled, +- const char* name, +- unsigned long long id, +- unsigned char flags) { - TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_enabled, name, id, - kZeroNumArgs, nullptr, nullptr, nullptr, - flags); -} - --template +-template -static inline void AddTraceEvent(char phase, -- const unsigned char* category_enabled, -- const char* name, -- unsigned long long id, -- unsigned char flags, -- const char* arg1_name, -- const ARG1_TYPE& arg1_val) { +- const unsigned char* category_enabled, +- const char* name, +- unsigned long long id, +- unsigned char flags, +- const char* arg1_name, +- const ARG1_TYPE& arg1_val) { - const int num_args = 1; - unsigned char arg_types[1]; - unsigned long long arg_values[1]; - SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); -- TRACE_EVENT_API_ADD_TRACE_EVENT( -- phase, category_enabled, name, id, -- num_args, &arg1_name, arg_types, arg_values, -- flags); +- TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_enabled, name, id, num_args, +- &arg1_name, arg_types, arg_values, flags); -} - --template +-template -static inline void AddTraceEvent(char phase, -- const unsigned char* category_enabled, -- const char* name, -- unsigned long long id, -- unsigned char flags, -- const char* arg1_name, -- const ARG1_TYPE& arg1_val, -- const char* arg2_name, -- const ARG2_TYPE& arg2_val) { +- const unsigned char* category_enabled, +- const char* name, +- unsigned long long id, +- unsigned char flags, +- const char* arg1_name, +- const ARG1_TYPE& arg1_val, +- const char* arg2_name, +- const ARG2_TYPE& arg2_val) { - const int num_args = 2; -- const char* arg_names[2] = { arg1_name, arg2_name }; +- const char* arg_names[2] = {arg1_name, arg2_name}; - unsigned char arg_types[2]; - unsigned long long arg_values[2]; - SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); - SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]); -- TRACE_EVENT_API_ADD_TRACE_EVENT( -- phase, category_enabled, name, id, -- num_args, arg_names, arg_types, arg_values, -- flags); +- TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_enabled, name, id, num_args, +- arg_names, arg_types, arg_values, flags); -} - -// Used by TRACE_EVENTx macro. Do not use directly. @@ -927,8 +936,7 @@ index e9a5c4c6f2..b34df0c93f 100644 - AddEventIfEnabled(); - } - -- void Initialize(const unsigned char* category_enabled, -- const char* name) { +- void Initialize(const unsigned char* category_enabled, const char* name) { - data_.category_enabled = category_enabled; - data_.name = name; - p_data_ = &data_; @@ -967,7 +975,9 @@ index e9a5c4c6f2..b34df0c93f 100644 -// This section defines no-op alternatives to the tracing macros when -// RTC_DISABLE_TRACE_EVENTS is defined. - --#define RTC_NOOP() do {} while (0) +-#define RTC_NOOP() \ +- do { \ +- } while (0) - -#define TRACE_STR_COPY(str) RTC_NOOP() - @@ -978,111 +988,131 @@ index e9a5c4c6f2..b34df0c93f 100644 -#define TRACE_EVENT0(category, name) RTC_NOOP() -#define TRACE_EVENT1(category, name, arg1_name, arg1_val) RTC_NOOP() -#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ -- RTC_NOOP() +- RTC_NOOP() - -#define TRACE_EVENT_INSTANT0(category, name) RTC_NOOP() -#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) RTC_NOOP() - --#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +-#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_COPY_INSTANT0(category, name) RTC_NOOP() -#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_BEGIN0(category, name) RTC_NOOP() -#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) RTC_NOOP() --#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +-#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_BEGIN0(category, name) RTC_NOOP() -#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) RTC_NOOP() -#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_END0(category, name) RTC_NOOP() -#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) RTC_NOOP() --#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +-#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_END0(category, name) RTC_NOOP() -#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) RTC_NOOP() --#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +-#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, arg2_name, \ +- arg2_val) \ +- RTC_NOOP() - -#define TRACE_COUNTER1(category, name, value) RTC_NOOP() -#define TRACE_COPY_COUNTER1(category, name, value) RTC_NOOP() - --#define TRACE_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) RTC_NOOP() +-#define TRACE_COUNTER2(category, name, value1_name, value1_val, value2_name, \ +- value2_val) \ +- RTC_NOOP() -#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ -- value2_name, value2_val) RTC_NOOP() +- value2_name, value2_val) \ +- RTC_NOOP() - -#define TRACE_COUNTER_ID1(category, name, id, value) RTC_NOOP() -#define TRACE_COPY_COUNTER_ID1(category, name, id, value) RTC_NOOP() - -#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) RTC_NOOP() +- value2_name, value2_val) \ +- RTC_NOOP() -#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ -- value2_name, value2_val) RTC_NOOP() +- value2_name, value2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) RTC_NOOP() --#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) RTC_NOOP() +-#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, arg1_name, arg1_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) RTC_NOOP() --#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) RTC_NOOP() +-#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, arg1_name, \ +- arg1_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_ASYNC_END0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_FLOW_BEGIN0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_BEGIN0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_BEGIN1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_BEGIN2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_FLOW_STEP0(category, name, id, step) RTC_NOOP() --#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) RTC_NOOP() +-#define TRACE_EVENT_FLOW_STEP1(category, name, id, step, arg1_name, arg1_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_STEP0(category, name, id, step) RTC_NOOP() --#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, \ -- arg1_name, arg1_val) RTC_NOOP() +-#define TRACE_EVENT_COPY_FLOW_STEP1(category, name, id, step, arg1_name, \ +- arg1_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_FLOW_END0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_FLOW_END1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_FLOW_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_END0(category, name, id) RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_END1(category, name, id, arg1_name, arg1_val) \ -- RTC_NOOP() +- RTC_NOOP() -#define TRACE_EVENT_COPY_FLOW_END2(category, name, id, arg1_name, arg1_val, \ -- arg2_name, arg2_val) RTC_NOOP() +- arg2_name, arg2_val) \ +- RTC_NOOP() - -#define TRACE_EVENT_API_GET_CATEGORY_ENABLED "" - diff --git a/third_party/libwebrtc/moz-patch-stack/0035.patch b/third_party/libwebrtc/moz-patch-stack/0035.patch index fa9d6371d9e94..f6a5b17f0c3db 100644 --- a/third_party/libwebrtc/moz-patch-stack/0035.patch +++ b/third_party/libwebrtc/moz-patch-stack/0035.patch @@ -28,37 +28,37 @@ Bug 1839451 - (fix-186ebdc1b0) remove BUILD.gn refs to gone files delayable.h, m Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d0f4d1733cb1a2d8189097af4b5537118ebc95a6 --- - .gn | 2 ++ - BUILD.gn | 35 +++++++++++++++++- - api/BUILD.gn | 32 +++++++++++++++-- - api/rtp_sender_interface.h | 4 +-- - api/rtp_sender_setparameters_callback.cc | 27 ++++++++++++++ - api/rtp_sender_setparameters_callback.h | 28 +++++++++++++++ - api/task_queue/BUILD.gn | 2 ++ - api/transport/BUILD.gn | 2 ++ - call/BUILD.gn | 14 ++++++-- + .gn | 2 + + BUILD.gn | 45 ++++++++++++++++++- + api/BUILD.gn | 32 ++++++++++++- + api/rtp_sender_interface.h | 4 +- + api/rtp_sender_setparameters_callback.cc | 27 +++++++++++ + api/rtp_sender_setparameters_callback.h | 28 ++++++++++++ + api/task_queue/BUILD.gn | 2 + + api/transport/BUILD.gn | 2 + + call/BUILD.gn | 14 +++++- call/audio_send_stream.h | 2 +- call/video_send_stream.h | 2 +- - common_audio/BUILD.gn | 4 --- - common_audio/fir_filter_avx2.cc | 2 ++ - common_audio/intrin.h | 8 +++++ - media/BUILD.gn | 35 +++++++++++++++++- - media/base/media_channel.h | 4 --- - media/base/media_channel_impl.cc | 13 ------- + common_audio/BUILD.gn | 4 -- + common_audio/fir_filter_avx2.cc | 2 + + common_audio/intrin.h | 8 ++++ + media/BUILD.gn | 35 ++++++++++++++- + media/base/media_channel.h | 4 -- + media/base/media_channel_impl.cc | 13 ------ modules/audio_coding/BUILD.gn | 2 +- - modules/audio_device/BUILD.gn | 19 +++++++--- - modules/audio_processing/aec3/BUILD.gn | 13 +++---- - .../aec3/adaptive_fir_filter_avx2.cc | 3 +- + modules/audio_device/BUILD.gn | 19 +++++--- + modules/audio_processing/aec3/BUILD.gn | 13 +++--- + .../aec3/adaptive_fir_filter_avx2.cc | 2 +- .../audio_processing/agc2/rnn_vad/BUILD.gn | 2 +- - modules/desktop_capture/BUILD.gn | 29 +-------------- - modules/portal/BUILD.gn | 24 +++++++++++++ - modules/video_capture/BUILD.gn | 11 +----- - rtc_base/BUILD.gn | 6 +++- + modules/desktop_capture/BUILD.gn | 29 +----------- + modules/portal/BUILD.gn | 24 ++++++++++ + modules/video_capture/BUILD.gn | 11 +---- + rtc_base/BUILD.gn | 6 ++- rtc_base/system/BUILD.gn | 2 +- - test/BUILD.gn | 14 ++++++++ - video/BUILD.gn | 4 +-- - webrtc.gni | 36 ++++++++++++------- - 30 files changed, 278 insertions(+), 103 deletions(-) + test/BUILD.gn | 14 ++++++ + video/BUILD.gn | 4 +- + webrtc.gni | 34 +++++++++----- + 30 files changed, 287 insertions(+), 101 deletions(-) create mode 100644 api/rtp_sender_setparameters_callback.cc create mode 100644 api/rtp_sender_setparameters_callback.h create mode 100644 common_audio/intrin.h @@ -77,7 +77,7 @@ index 445772fada..c280fae405 100644 # TODO(https://bugs.webrtc.org/14437): Remove this section if general # Chromium fix resolves the problem. diff --git a/BUILD.gn b/BUILD.gn -index 26773551ad..4c23fdf957 100644 +index d5289b85d7..8356dfe0bf 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -32,7 +32,7 @@ if (is_android) { @@ -112,7 +112,7 @@ index 26773551ad..4c23fdf957 100644 if (!build_with_chromium) { # Target to build all the WebRTC production code. -@@ -508,6 +514,23 @@ if (!build_with_chromium) { +@@ -518,6 +524,33 @@ if (!build_with_chromium) { "sdk", "video", ] @@ -126,6 +126,16 @@ index 26773551ad..4c23fdf957 100644 + "api/task_queue", + "api/task_queue:default_task_queue_factory", + "api/test/metrics", ++ "api/video_codecs:video_decoder_factory_template", ++ "api/video_codecs:video_decoder_factory_template_dav1d_adapter", ++ "api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", ++ "api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", ++ "api/video_codecs:video_decoder_factory_template_open_h264_adapter", ++ "api/video_codecs:video_encoder_factory_template", ++ "api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", ++ "api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", ++ "api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", ++ "api/video_codecs:video_encoder_factory_template_open_h264_adapter", + "logging:rtc_event_log_api", + "p2p:rtc_p2p", + "pc:libjingle_peerconnection", @@ -136,7 +146,7 @@ index 26773551ad..4c23fdf957 100644 if (rtc_include_builtin_audio_codecs) { deps += [ -@@ -527,6 +550,16 @@ if (!build_with_chromium) { +@@ -530,6 +563,16 @@ if (!build_with_chromium) { deps += [ "api/video:video_frame", "api/video:video_rtp_headers", @@ -154,7 +164,7 @@ index 26773551ad..4c23fdf957 100644 } else { deps += [ diff --git a/api/BUILD.gn b/api/BUILD.gn -index 2ad89c9202..abc92cf4a8 100644 +index a0a9563ce0..4ca73b99f5 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -35,7 +35,7 @@ rtc_source_set("callfactory_api") { @@ -239,7 +249,7 @@ index 2ad89c9202..abc92cf4a8 100644 rtc_source_set("frame_transformer_interface") { visibility = [ "*" ] -@@ -564,6 +588,7 @@ rtc_source_set("peer_network_dependencies") { +@@ -565,6 +589,7 @@ rtc_source_set("peer_network_dependencies") { } rtc_source_set("peer_connection_quality_test_fixture_api") { @@ -247,7 +257,7 @@ index 2ad89c9202..abc92cf4a8 100644 visibility = [ "*" ] testonly = true sources = [ "test/peerconnection_quality_test_fixture.h" ] -@@ -614,6 +639,7 @@ rtc_source_set("peer_connection_quality_test_fixture_api") { +@@ -615,6 +640,7 @@ rtc_source_set("peer_connection_quality_test_fixture_api") { "//third_party/abseil-cpp/absl/types:optional", ] } @@ -255,7 +265,7 @@ index 2ad89c9202..abc92cf4a8 100644 rtc_source_set("frame_generator_api") { visibility = [ "*" ] -@@ -898,6 +924,7 @@ rtc_source_set("refcountedbase") { +@@ -899,6 +925,7 @@ rtc_source_set("refcountedbase") { ] } @@ -263,7 +273,7 @@ index 2ad89c9202..abc92cf4a8 100644 rtc_library("ice_transport_factory") { visibility = [ "*" ] sources = [ -@@ -916,6 +943,7 @@ rtc_library("ice_transport_factory") { +@@ -917,6 +944,7 @@ rtc_library("ice_transport_factory") { "rtc_event_log:rtc_event_log", ] } @@ -395,7 +405,7 @@ index 12a1f57066..d8f095c700 100644 if (rtc_include_tests) { rtc_source_set("test_feedback_generator_interface") { diff --git a/call/BUILD.gn b/call/BUILD.gn -index 0e52e8fb3f..154d2bd445 100644 +index 63a3a2d53d..a85ad0c0d4 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -46,7 +46,7 @@ rtc_library("call_interfaces") { @@ -434,7 +444,7 @@ index 0e52e8fb3f..154d2bd445 100644 "../api:transport_api", "../api/adaptation:resource_adaptation_api", diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h -index 0f42d0fb82..369d065f66 100644 +index 9c2fad652f..f9e49db574 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h @@ -25,7 +25,7 @@ @@ -506,7 +516,7 @@ index 0000000000..f6ff7f218f + #endif +#endif diff --git a/media/BUILD.gn b/media/BUILD.gn -index 8f85067624..3c4f757155 100644 +index cf0f3d3bd8..a3d03da735 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -64,7 +64,7 @@ rtc_library("rtc_media_base") { @@ -628,7 +638,7 @@ index 8f85067624..3c4f757155 100644 rtc_library("rtc_audio_video") { diff --git a/media/base/media_channel.h b/media/base/media_channel.h -index cf52244ba0..ab4eb79508 100644 +index 378042f1b2..3ce7327fea 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -64,10 +64,6 @@ class Timing; @@ -667,7 +677,7 @@ index ca2a117fd1..f323503d59 100644 using webrtc::FrameDecryptorInterface; using webrtc::FrameEncryptorInterface; diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn -index fc07126462..6c1f812c0f 100644 +index 1420aa6385..143a6eca41 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -553,7 +553,7 @@ rtc_library("webrtc_opus_wrapper") { @@ -680,7 +690,7 @@ index fc07126462..6c1f812c0f 100644 } diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn -index 4a6a0ab41c..61cd531edd 100644 +index 260ac14293..ab8ec28ba2 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -30,6 +30,7 @@ rtc_source_set("audio_device_default") { @@ -715,7 +725,7 @@ index 4a6a0ab41c..61cd531edd 100644 rtc_library("audio_device_generic") { sources = [ -@@ -180,6 +184,7 @@ rtc_source_set("audio_device_module_from_input_and_output") { +@@ -210,6 +214,7 @@ rtc_library("test_audio_device_module") { # Contains default implementations of webrtc::AudioDeviceModule for Windows, # Linux, Mac, iOS and Android. rtc_library("audio_device_impl") { @@ -723,7 +733,7 @@ index 4a6a0ab41c..61cd531edd 100644 visibility = [ "*" ] deps = [ ":audio_device_api", -@@ -233,9 +238,9 @@ rtc_library("audio_device_impl") { +@@ -261,9 +266,9 @@ rtc_library("audio_device_impl") { ] if (build_with_mozilla) { @@ -736,7 +746,7 @@ index 4a6a0ab41c..61cd531edd 100644 ] } -@@ -373,6 +378,7 @@ rtc_library("audio_device_impl") { +@@ -401,6 +406,7 @@ rtc_library("audio_device_impl") { ] } } @@ -744,7 +754,7 @@ index 4a6a0ab41c..61cd531edd 100644 if (is_mac) { rtc_source_set("audio_device_impl_frameworks") { -@@ -390,6 +396,7 @@ if (is_mac) { +@@ -418,6 +424,7 @@ if (is_mac) { } } @@ -752,7 +762,7 @@ index 4a6a0ab41c..61cd531edd 100644 rtc_source_set("mock_audio_device") { visibility = [ "*" ] testonly = true -@@ -406,8 +413,10 @@ rtc_source_set("mock_audio_device") { +@@ -434,8 +441,10 @@ rtc_source_set("mock_audio_device") { "../../test:test_support", ] } @@ -764,7 +774,7 @@ index 4a6a0ab41c..61cd531edd 100644 rtc_library("audio_device_unittests") { testonly = true -@@ -477,7 +486,7 @@ if (rtc_include_tests && !build_with_chromium) { +@@ -506,7 +515,7 @@ if (rtc_include_tests && !build_with_chromium) { } } @@ -798,19 +808,18 @@ index f5eb5d5951..3e11a245a1 100644 deps = [ ":adaptive_fir_filter", diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc b/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc -index 6c8c948026..44d4514275 100644 +index b6eda9f117..8d6e1cf3d7 100644 --- a/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc +++ b/modules/audio_processing/aec3/adaptive_fir_filter_avx2.cc -@@ -10,8 +10,7 @@ - - #include "modules/audio_processing/aec3/adaptive_fir_filter.h" +@@ -8,7 +8,7 @@ + * be found in the AUTHORS file in the root of the source tree. + */ -#include -- +#include "common_audio/intrin.h" - #include "rtc_base/checks.h" - namespace webrtc { + #include "modules/audio_processing/aec3/adaptive_fir_filter.h" + #include "rtc_base/checks.h" diff --git a/modules/audio_processing/agc2/rnn_vad/BUILD.gn b/modules/audio_processing/agc2/rnn_vad/BUILD.gn index 9093a68cf3..3003a585bd 100644 --- a/modules/audio_processing/agc2/rnn_vad/BUILD.gn @@ -1005,10 +1014,10 @@ index 77f5139a2f..486b37590c 100644 deps += [ "..:logging", diff --git a/test/BUILD.gn b/test/BUILD.gn -index a7cd3427d6..6fd790332b 100644 +index bda12289c2..55153909d3 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn -@@ -175,6 +175,7 @@ rtc_library("audio_test_common") { +@@ -240,6 +240,7 @@ rtc_library("audio_test_common") { absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] } @@ -1016,7 +1025,7 @@ index a7cd3427d6..6fd790332b 100644 if (!build_with_chromium) { if (is_mac || is_ios) { rtc_library("video_test_mac") { -@@ -223,8 +224,12 @@ if (!build_with_chromium) { +@@ -292,8 +293,12 @@ if (!build_with_chromium) { } } } @@ -1029,7 +1038,7 @@ index a7cd3427d6..6fd790332b 100644 testonly = true sources = [ "rtcp_packet_parser.cc", -@@ -234,6 +239,7 @@ rtc_library("rtp_test_utils") { +@@ -303,6 +308,7 @@ rtc_library("rtp_test_utils") { "rtp_file_writer.cc", "rtp_file_writer.h", ] @@ -1037,7 +1046,7 @@ index a7cd3427d6..6fd790332b 100644 deps = [ "../api:array_view", -@@ -486,7 +492,9 @@ rtc_library("video_test_support") { +@@ -555,7 +561,9 @@ rtc_library("video_test_support") { absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] if (!is_ios) { @@ -1047,7 +1056,7 @@ index a7cd3427d6..6fd790332b 100644 sources += [ "testsupport/jpeg_frame_writer.cc" ] } else { sources += [ "testsupport/jpeg_frame_writer_ios.cc" ] -@@ -1060,6 +1068,10 @@ rtc_library("test_common") { +@@ -1140,6 +1148,10 @@ rtc_library("test_common") { if (!is_android && !build_with_chromium) { deps += [ "../modules/video_capture:video_capture_internal_impl" ] } @@ -1058,7 +1067,7 @@ index a7cd3427d6..6fd790332b 100644 } rtc_library("mock_transport") { -@@ -1227,6 +1239,7 @@ rtc_library("copy_to_file_audio_capturer_unittest") { +@@ -1307,6 +1319,7 @@ rtc_library("copy_to_file_audio_capturer_unittest") { ] } @@ -1066,7 +1075,7 @@ index a7cd3427d6..6fd790332b 100644 if (!build_with_chromium && is_android) { rtc_android_library("native_test_java") { testonly = true -@@ -1240,6 +1253,7 @@ if (!build_with_chromium && is_android) { +@@ -1320,6 +1333,7 @@ if (!build_with_chromium && is_android) { ] } } @@ -1075,7 +1084,7 @@ index a7cd3427d6..6fd790332b 100644 rtc_library("call_config_utils") { # TODO(bugs.webrtc.org/10814): Remove rtc_json_suppressions as soon as it diff --git a/video/BUILD.gn b/video/BUILD.gn -index 3161435cb3..3139fc8710 100644 +index e4d3c51c36..ea8bbdfbb2 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -17,7 +17,7 @@ rtc_library("video_stream_encoder_interface") { @@ -1097,7 +1106,7 @@ index 3161435cb3..3139fc8710 100644 "../api/adaptation:resource_adaptation_api", "../api/task_queue:pending_task_safety_flag", diff --git a/webrtc.gni b/webrtc.gni -index 823dfa7418..d1f9de6968 100644 +index 5e4a5d3c81..7a17c8f35f 100644 --- a/webrtc.gni +++ b/webrtc.gni @@ -35,6 +35,11 @@ if (is_mac) { @@ -1169,16 +1178,7 @@ index 823dfa7418..d1f9de6968 100644 # Experimental: enable use of Android AAudio which requires Android SDK 26 or above # and NDK r16 or above. rtc_enable_android_aaudio = false -@@ -218,7 +225,7 @@ declare_args() { - # video codecs they depends on will not be included in libwebrtc.{a|lib} - # (they will still be included in libjingle_peerconnection_so.so and - # WebRTC.framework) -- rtc_include_builtin_video_codecs = true -+ rtc_include_builtin_video_codecs = !build_with_mozilla # See Bug 1820869. - - # When set to true and in a standalone build, it will undefine UNICODE and - # _UNICODE (which are always defined globally by the Chromium Windows -@@ -231,7 +238,7 @@ declare_args() { +@@ -225,7 +232,7 @@ declare_args() { # When set to true, a capturer implementation that uses the # Windows.Graphics.Capture APIs will be available for use. This introduces a # dependency on the Win 10 SDK v10.0.17763.0. @@ -1187,7 +1187,7 @@ index 823dfa7418..d1f9de6968 100644 # Includes the dav1d decoder in the internal decoder factory when set to true. rtc_include_dav1d_in_internal_decoder_factory = true -@@ -266,7 +273,7 @@ declare_args() { +@@ -260,7 +267,7 @@ declare_args() { rtc_build_json = !build_with_mozilla rtc_build_libsrtp = !build_with_mozilla rtc_build_libvpx = !build_with_mozilla @@ -1196,7 +1196,7 @@ index 823dfa7418..d1f9de6968 100644 rtc_build_opus = !build_with_mozilla rtc_build_ssl = !build_with_mozilla -@@ -285,7 +292,7 @@ declare_args() { +@@ -279,7 +286,7 @@ declare_args() { # Chromium uses its own IO handling, so the internal ADM is only built for # standalone WebRTC. @@ -1205,7 +1205,7 @@ index 823dfa7418..d1f9de6968 100644 # Set this to true to enable the avx2 support in webrtc. # TODO: Make sure that AVX2 works also for non-clang compilers. -@@ -329,6 +336,9 @@ declare_args() { +@@ -323,6 +330,9 @@ declare_args() { rtc_enable_grpc = rtc_enable_protobuf && (is_linux || is_mac) } @@ -1215,7 +1215,7 @@ index 823dfa7418..d1f9de6968 100644 # Make it possible to provide custom locations for some libraries (move these # up into declare_args should we need to actually use them for the GN build). rtc_libvpx_dir = "//third_party/libvpx" -@@ -1124,7 +1134,7 @@ if (is_mac || is_ios) { +@@ -1118,7 +1128,7 @@ if (is_mac || is_ios) { } } diff --git a/third_party/libwebrtc/moz-patch-stack/0036.patch b/third_party/libwebrtc/moz-patch-stack/0036.patch index 8fd7ad76e6aaf..23be8ed211aff 100644 --- a/third_party/libwebrtc/moz-patch-stack/0036.patch +++ b/third_party/libwebrtc/moz-patch-stack/0036.patch @@ -9,7 +9,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/7163801a480d60700 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/audio/channel_send.cc b/audio/channel_send.cc -index 3e734aab45..508bbd615a 100644 +index 91a17d4d72..6a34a9ad44 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -696,9 +696,9 @@ void ChannelSend::SetSendAudioLevelIndicationStatus(bool enable, int id) { diff --git a/third_party/libwebrtc/moz-patch-stack/0039.patch b/third_party/libwebrtc/moz-patch-stack/0039.patch index 3943e76556c39..8c59cc2f32948 100644 --- a/third_party/libwebrtc/moz-patch-stack/0039.patch +++ b/third_party/libwebrtc/moz-patch-stack/0039.patch @@ -15,10 +15,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d380a43d59f4f7cbc 4 files changed, 35 insertions(+) diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc -index 7d6ec794d4..20af3f7722 100644 +index e0ad1a8bd6..9330932e3c 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc -@@ -442,6 +442,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( +@@ -436,6 +436,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( stats.target_bitrate_bps = channel_send_->GetTargetBitrate(); webrtc::CallSendStatistics call_stats = channel_send_->GetRTCPStatistics(); @@ -27,7 +27,7 @@ index 7d6ec794d4..20af3f7722 100644 stats.header_and_padding_bytes_sent = call_stats.header_and_padding_bytes_sent; diff --git a/audio/channel_send.cc b/audio/channel_send.cc -index 508bbd615a..13248a482a 100644 +index 6a34a9ad44..c81758eb63 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -56,6 +56,31 @@ class RtpPacketSenderProxy; @@ -97,7 +97,7 @@ index 508bbd615a..13248a482a 100644 StreamDataCounters rtp_stats; StreamDataCounters rtx_stats; diff --git a/audio/channel_send.h b/audio/channel_send.h -index cf9a273f70..9b3969161c 100644 +index 08d3f92f1d..47361882d5 100644 --- a/audio/channel_send.h +++ b/audio/channel_send.h @@ -43,6 +43,7 @@ struct CallSendStatistics { @@ -109,7 +109,7 @@ index cf9a273f70..9b3969161c 100644 // Within this list, the sender-source SSRC pair is unique and per-pair the // ReportBlockData represents the latest Report Block that was received for diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h -index 369d065f66..187ec65ed8 100644 +index f9e49db574..5f4f871bf0 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h @@ -31,6 +31,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/0042.patch b/third_party/libwebrtc/moz-patch-stack/0042.patch index a65571742f827..0489ce5e62a6c 100644 --- a/third_party/libwebrtc/moz-patch-stack/0042.patch +++ b/third_party/libwebrtc/moz-patch-stack/0042.patch @@ -13,7 +13,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/24809d566449907ed 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index 3ab95837c0..6b4c57d01e 100644 +index e1a16e979c..299be99502 100644 --- a/modules/video_capture/windows/device_info_ds.cc +++ b/modules/video_capture/windows/device_info_ds.cc @@ -172,7 +172,8 @@ int32_t DeviceInfoDS::GetDeviceName(uint32_t deviceNumber, diff --git a/third_party/libwebrtc/moz-patch-stack/0047.patch b/third_party/libwebrtc/moz-patch-stack/0047.patch index 08b29e39ee323..bd1ad24755ade 100644 --- a/third_party/libwebrtc/moz-patch-stack/0047.patch +++ b/third_party/libwebrtc/moz-patch-stack/0047.patch @@ -20,7 +20,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/58f47eacaf10d12e2 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/BUILD.gn b/BUILD.gn -index 4c23fdf957..a2ab84ab69 100644 +index 8356dfe0bf..9c3f5d94e9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -413,12 +413,12 @@ config("common_config") { @@ -276,7 +276,7 @@ index 42d72865b9..c184e2fbbc 100644 config("x11_config") { if (rtc_use_x11_extensions) { diff --git a/webrtc.gni b/webrtc.gni -index d1f9de6968..aa304001c7 100644 +index 7a17c8f35f..099db9e1ac 100644 --- a/webrtc.gni +++ b/webrtc.gni @@ -171,13 +171,13 @@ declare_args() { diff --git a/third_party/libwebrtc/moz-patch-stack/0048.patch b/third_party/libwebrtc/moz-patch-stack/0048.patch index 870e2e701a5be..6dd655d692e44 100644 --- a/third_party/libwebrtc/moz-patch-stack/0048.patch +++ b/third_party/libwebrtc/moz-patch-stack/0048.patch @@ -20,7 +20,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d0b311007c033e838 11 files changed, 56 insertions(+), 10 deletions(-) diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc -index 7430681f45..85fe185d90 100644 +index bde48aacde..0a78e2641d 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc @@ -39,6 +39,8 @@ std::string AudioReceiveStreamInterface::Config::Rtp::ToString() const { @@ -43,7 +43,7 @@ index 7430681f45..85fe185d90 100644 } // namespace diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc -index 9c3f52a651..9697ed0d1a 100644 +index e6435ad1b1..9a1abd5bfa 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -102,7 +102,8 @@ class ChannelReceive : public ChannelReceiveInterface, @@ -93,7 +93,7 @@ index 9c3f52a651..9697ed0d1a 100644 } // namespace voe diff --git a/audio/channel_receive.h b/audio/channel_receive.h -index d1d24e540f..60cfaa3355 100644 +index 13edf04053..c192039894 100644 --- a/audio/channel_receive.h +++ b/audio/channel_receive.h @@ -186,7 +186,8 @@ std::unique_ptr CreateChannelReceive( @@ -107,7 +107,7 @@ index d1d24e540f..60cfaa3355 100644 } // namespace voe } // namespace webrtc diff --git a/call/audio_receive_stream.h b/call/audio_receive_stream.h -index 64fdf66925..c21a6b3f1f 100644 +index b0e94fee2a..acafff9e32 100644 --- a/call/audio_receive_stream.h +++ b/call/audio_receive_stream.h @@ -19,6 +19,7 @@ @@ -181,7 +181,7 @@ index 6e558e1e1d..d95abf7286 100644 static constexpr size_t kNumMediaTypes = 5; enum class RtpPacketMediaType : size_t { diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc -index a8e99cbd14..39a151bc47 100644 +index 3210e7a9e3..e883668eac 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -145,6 +145,7 @@ RTCPReceiver::RTCPReceiver(const RtpRtcpInterface::Configuration& config, @@ -200,7 +200,7 @@ index a8e99cbd14..39a151bc47 100644 rtcp_intra_frame_observer_(config.intra_frame_callback), rtcp_loss_notification_observer_(config.rtcp_loss_notification_observer), network_state_estimate_observer_(config.network_state_estimate_observer), -@@ -823,6 +825,10 @@ bool RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) { +@@ -812,6 +814,10 @@ bool RTCPReceiver::HandleBye(const CommonHeader& rtcp_block) { return false; } @@ -211,7 +211,7 @@ index a8e99cbd14..39a151bc47 100644 // Clear our lists. rtts_.erase(bye.sender_ssrc()); EraseIf(received_report_blocks_, [&](const auto& elem) { -@@ -1245,12 +1251,20 @@ std::vector RTCPReceiver::TmmbrReceived() { +@@ -1234,12 +1240,20 @@ std::vector RTCPReceiver::TmmbrReceived() { } bool RTCPReceiver::RtcpRrTimeoutLocked(Timestamp now) { @@ -247,7 +247,7 @@ index 68bb16bd8b..3864aa3144 100644 RtcpLossNotificationObserver* const rtcp_loss_notification_observer_; NetworkStateEstimateObserver* const network_state_estimate_observer_; diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -index 3be50835a4..c07e50b5a3 100644 +index b791a5c88d..3211097eeb 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h @@ -73,6 +73,9 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { diff --git a/third_party/libwebrtc/moz-patch-stack/0051.patch b/third_party/libwebrtc/moz-patch-stack/0051.patch index 5a487f124f4d6..82a9d12682170 100644 --- a/third_party/libwebrtc/moz-patch-stack/0051.patch +++ b/third_party/libwebrtc/moz-patch-stack/0051.patch @@ -9,20 +9,20 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/de8c14e4972f717bf 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/rtp_rtcp/source/source_tracker.cc b/modules/rtp_rtcp/source/source_tracker.cc -index 7a5cbac77d..65f21700d0 100644 +index 13d848dce0..46a46ef51d 100644 --- a/modules/rtp_rtcp/source/source_tracker.cc +++ b/modules/rtp_rtcp/source/source_tracker.cc -@@ -36,7 +36,8 @@ void SourceTracker::OnFrameDelivered(const RtpPacketInfos& packet_infos) { +@@ -47,7 +47,8 @@ void SourceTracker::OnFrameDeliveredInternal( SourceKey key(RtpSourceType::CSRC, csrc); SourceEntry& entry = UpdateEntry(key); -- entry.timestamp_ms = now_ms; -+ const auto packet_time = packet_info.receive_time().ms(); -+ entry.timestamp_ms = packet_time ? packet_time : now_ms; +- entry.timestamp = now; ++ const auto packet_time = packet_info.receive_time(); ++ entry.timestamp = packet_time.ms() ? packet_time : now; entry.audio_level = packet_info.audio_level(); entry.absolute_capture_time = packet_info.absolute_capture_time(); entry.local_capture_clock_offset = -@@ -77,6 +78,10 @@ std::vector SourceTracker::GetSources() const { +@@ -86,6 +87,10 @@ std::vector SourceTracker::GetSources() const { .local_capture_clock_offset = entry.local_capture_clock_offset}); } diff --git a/third_party/libwebrtc/moz-patch-stack/0052.patch b/third_party/libwebrtc/moz-patch-stack/0052.patch index 0eb22cde14181..95e420357732b 100644 --- a/third_party/libwebrtc/moz-patch-stack/0052.patch +++ b/third_party/libwebrtc/moz-patch-stack/0052.patch @@ -12,7 +12,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/1965757ee924d49c3 1 file changed, 1 insertion(+) diff --git a/audio/channel_receive.h b/audio/channel_receive.h -index 60cfaa3355..5fbfb8a240 100644 +index c192039894..37bf903394 100644 --- a/audio/channel_receive.h +++ b/audio/channel_receive.h @@ -28,6 +28,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/0053.patch b/third_party/libwebrtc/moz-patch-stack/0053.patch index 9d5113e7004ed..f689f02282e36 100644 --- a/third_party/libwebrtc/moz-patch-stack/0053.patch +++ b/third_party/libwebrtc/moz-patch-stack/0053.patch @@ -16,10 +16,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c186df8a088e46285 1 file changed, 1 deletion(-) diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc -index 85fe185d90..d76c1856d8 100644 +index 0a78e2641d..8a3ac93a36 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc -@@ -369,7 +369,6 @@ int AudioReceiveStreamImpl::GetBaseMinimumPlayoutDelayMs() const { +@@ -367,7 +367,6 @@ int AudioReceiveStreamImpl::GetBaseMinimumPlayoutDelayMs() const { } std::vector AudioReceiveStreamImpl::GetSources() const { diff --git a/third_party/libwebrtc/moz-patch-stack/0056.patch b/third_party/libwebrtc/moz-patch-stack/0056.patch index 376e9f818cf5b..d04d60ba85e96 100644 --- a/third_party/libwebrtc/moz-patch-stack/0056.patch +++ b/third_party/libwebrtc/moz-patch-stack/0056.patch @@ -37,7 +37,7 @@ index 87fd54fd1c..18b8a71e3c 100644 // Timing frame info: all important timestamps for a full lifetime of a // single 'timing frame'. diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc -index 39a151bc47..e00761726c 100644 +index e883668eac..da653cd68a 100644 --- a/modules/rtp_rtcp/source/rtcp_receiver.cc +++ b/modules/rtp_rtcp/source/rtcp_receiver.cc @@ -396,11 +396,13 @@ RTCPReceiver::ConsumeReceivedXrReferenceTimeInfo() { @@ -71,10 +71,10 @@ index 3864aa3144..cef0835417 100644 // Get rtt. int32_t RTT(uint32_t remote_ssrc, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -index f5c1f96df4..eb0acddefa 100644 +index ac3773fef7..4aa4b1aab5 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc -@@ -507,11 +507,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( +@@ -506,11 +506,11 @@ void ModuleRtpRtcpImpl::GetSendStreamDataCounters( } // Received RTCP report. @@ -106,10 +106,10 @@ index d9891166d6..fb74d2b946 100644 // A snapshot of the most recent Report Block with additional data of // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -index 573dc93679..1e01861665 100644 +index 9407b79b52..016d27db5d 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc -@@ -487,11 +487,11 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( +@@ -486,11 +486,11 @@ void ModuleRtpRtcpImpl2::GetSendStreamDataCounters( } // Received RTCP report. @@ -141,10 +141,10 @@ index 00d01df6ea..8c2c6e5765 100644 // A snapshot of the most recent Report Block with additional data of // interest to statistics. Used to implement RTCRemoteInboundRtpStreamStats. diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -index c07e50b5a3..d7b0d3d1c8 100644 +index 3211097eeb..776d36efbc 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h -@@ -397,10 +397,11 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { +@@ -396,10 +396,11 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface { StreamDataCounters* rtx_counters) const = 0; diff --git a/third_party/libwebrtc/moz-patch-stack/0058.patch b/third_party/libwebrtc/moz-patch-stack/0058.patch index 4959f064cebe9..370a93396a96a 100644 --- a/third_party/libwebrtc/moz-patch-stack/0058.patch +++ b/third_party/libwebrtc/moz-patch-stack/0058.patch @@ -24,7 +24,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0744d68b8c944e699 10 files changed, 18 insertions(+), 6 deletions(-) diff --git a/audio/channel_send.cc b/audio/channel_send.cc -index 13248a482a..d6e1d1cea1 100644 +index c81758eb63..f6b9767655 100644 --- a/audio/channel_send.cc +++ b/audio/channel_send.cc @@ -505,7 +505,7 @@ ChannelSend::ChannelSend( @@ -37,7 +37,7 @@ index 13248a482a..d6e1d1cea1 100644 configuration.outgoing_transport = rtp_transport; diff --git a/call/call.cc b/call/call.cc -index ccfed35785..02f8e71d80 100644 +index b55492e53f..46c1dd3b9e 100644 --- a/call/call.cc +++ b/call/call.cc @@ -478,12 +478,14 @@ std::string Call::Stats::ToString(int64_t time_ms) const { @@ -78,7 +78,7 @@ index 380e80ce12..253f8cd7de 100644 std::unique_ptr CreateCallFactory() { diff --git a/call/degraded_call.cc b/call/degraded_call.cc -index fc76c7be5c..99c32296c3 100644 +index 3f47fcded0..114be134ab 100644 --- a/call/degraded_call.cc +++ b/call/degraded_call.cc @@ -129,6 +129,7 @@ bool DegradedCall::FakeNetworkPipeTransportAdapter::SendRtcp( @@ -111,10 +111,10 @@ index a77e472ec1..a5bf88e547 100644 // Conference Mixer relies on VAD decisions and fails without them. neteq_config.enable_post_decode_vad = true; diff --git a/modules/rtp_rtcp/include/flexfec_receiver.h b/modules/rtp_rtcp/include/flexfec_receiver.h -index 3cf4c3845e..29d9e72786 100644 +index a869c8ad41..b6a33882d1 100644 --- a/modules/rtp_rtcp/include/flexfec_receiver.h +++ b/modules/rtp_rtcp/include/flexfec_receiver.h -@@ -29,9 +29,11 @@ class Clock; +@@ -30,9 +30,11 @@ class Clock; class FlexfecReceiver { public: @@ -127,10 +127,10 @@ index 3cf4c3845e..29d9e72786 100644 uint32_t ssrc, uint32_t protected_media_ssrc, diff --git a/modules/rtp_rtcp/source/flexfec_receiver.cc b/modules/rtp_rtcp/source/flexfec_receiver.cc -index 3f345cd6d2..bd67de1f83 100644 +index 132ed164f9..d852c32e3c 100644 --- a/modules/rtp_rtcp/source/flexfec_receiver.cc +++ b/modules/rtp_rtcp/source/flexfec_receiver.cc -@@ -29,6 +29,7 @@ constexpr int kPacketLogIntervalMs = 10000; +@@ -31,6 +31,7 @@ constexpr TimeDelta kPacketLogInterval = TimeDelta::Seconds(10); } // namespace @@ -138,7 +138,7 @@ index 3f345cd6d2..bd67de1f83 100644 FlexfecReceiver::FlexfecReceiver( uint32_t ssrc, uint32_t protected_media_ssrc, -@@ -37,6 +38,7 @@ FlexfecReceiver::FlexfecReceiver( +@@ -39,6 +40,7 @@ FlexfecReceiver::FlexfecReceiver( ssrc, protected_media_ssrc, recovered_packet_receiver) {} diff --git a/third_party/libwebrtc/moz-patch-stack/0059.patch b/third_party/libwebrtc/moz-patch-stack/0059.patch index e90aea8c9d925..0c97f1a467c45 100644 --- a/third_party/libwebrtc/moz-patch-stack/0059.patch +++ b/third_party/libwebrtc/moz-patch-stack/0059.patch @@ -18,7 +18,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0300b32b7de70fb89 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/BUILD.gn b/BUILD.gn -index a2ab84ab69..6b35023104 100644 +index 9c3f5d94e9..b682bdc091 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -215,6 +215,9 @@ config("common_inherited_config") { @@ -74,10 +74,10 @@ index d64ea689bb..c3c6955a7b 100644 #endif // defined(WEBRTC_POSIX) } diff --git a/webrtc.gni b/webrtc.gni -index aa304001c7..7aab630ab1 100644 +index 099db9e1ac..e4ed834aec 100644 --- a/webrtc.gni +++ b/webrtc.gni -@@ -346,7 +346,7 @@ rtc_opus_dir = "//third_party/opus" +@@ -340,7 +340,7 @@ rtc_opus_dir = "//third_party/opus" # Desktop capturer is supported only on Windows, OSX and Linux. rtc_desktop_capture_supported = diff --git a/third_party/libwebrtc/moz-patch-stack/0060.patch b/third_party/libwebrtc/moz-patch-stack/0060.patch index ff0504a4f109d..8a56195f6c755 100644 --- a/third_party/libwebrtc/moz-patch-stack/0060.patch +++ b/third_party/libwebrtc/moz-patch-stack/0060.patch @@ -15,7 +15,7 @@ Subject: Bug 1766646 - (fix) breakout Call::Stats and SharedModuleThread into create mode 100644 call/call_basic_stats.h diff --git a/call/BUILD.gn b/call/BUILD.gn -index 154d2bd445..2bc7aaec92 100644 +index a85ad0c0d4..20e9241a83 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -33,6 +33,12 @@ rtc_library("call_interfaces") { @@ -32,7 +32,7 @@ index 154d2bd445..2bc7aaec92 100644 deps = [ ":audio_sender_interface", diff --git a/call/call.cc b/call/call.cc -index 02f8e71d80..85dbd2adfa 100644 +index 46c1dd3b9e..0421a21ee3 100644 --- a/call/call.cc +++ b/call/call.cc @@ -465,19 +465,6 @@ class Call final : public webrtc::Call, @@ -147,10 +147,10 @@ index 0000000000..98febe9405 + +#endif // CALL_CALL_BASIC_STATS_H_ diff --git a/video/video_send_stream.h b/video/video_send_stream.h -index a7ce112b21..404873fd39 100644 +index 1f4717fbec..55103ac979 100644 --- a/video/video_send_stream.h +++ b/video/video_send_stream.h -@@ -37,7 +37,6 @@ namespace test { +@@ -36,7 +36,6 @@ namespace test { class VideoSendStreamPeer; } // namespace test diff --git a/third_party/libwebrtc/moz-patch-stack/0062.patch b/third_party/libwebrtc/moz-patch-stack/0062.patch index 32d366d23e9b5..09e0f1055e8bb 100644 --- a/third_party/libwebrtc/moz-patch-stack/0062.patch +++ b/third_party/libwebrtc/moz-patch-stack/0062.patch @@ -3,20 +3,18 @@ Date: Thu, 28 Apr 2022 10:53:43 -0500 Subject: Bug 1766646 - (fix-a0bb2ef2dc) add back VideoType enum values --- - common_video/libyuv/include/webrtc_libyuv.h | 4 ++++ - common_video/libyuv/webrtc_libyuv.cc | 11 +++++++++++ - 2 files changed, 15 insertions(+) + common_video/libyuv/include/webrtc_libyuv.h | 3 +++ + common_video/libyuv/webrtc_libyuv.cc | 9 +++++++++ + 2 files changed, 12 insertions(+) diff --git a/common_video/libyuv/include/webrtc_libyuv.h b/common_video/libyuv/include/webrtc_libyuv.h -index 08a035a8d7..6d9071bcd5 100644 +index 68831c70ab..253a33294d 100644 --- a/common_video/libyuv/include/webrtc_libyuv.h +++ b/common_video/libyuv/include/webrtc_libyuv.h -@@ -32,12 +32,16 @@ enum class VideoType { - kI420, - kIYUV, - kRGB24, -+ kABGR, +@@ -35,11 +35,14 @@ enum class VideoType { + kBGR24, kARGB, + kABGR, + kARGB4444, kRGB565, + kARGB1555, @@ -29,7 +27,7 @@ index 08a035a8d7..6d9071bcd5 100644 kNV12, }; diff --git a/common_video/libyuv/webrtc_libyuv.cc b/common_video/libyuv/webrtc_libyuv.cc -index 46322501ad..4c6911b4a3 100644 +index 31ba1feca3..05a4b184c2 100644 --- a/common_video/libyuv/webrtc_libyuv.cc +++ b/common_video/libyuv/webrtc_libyuv.cc @@ -24,6 +24,7 @@ size_t CalcBufferSize(VideoType type, int width, int height) { @@ -50,16 +48,7 @@ index 46322501ad..4c6911b4a3 100644 case VideoType::kYUY2: case VideoType::kUYVY: return width * height * 2; -@@ -90,6 +93,8 @@ int ConvertVideoType(VideoType video_type) { - return libyuv::FOURCC_YV12; - case VideoType::kRGB24: - return libyuv::FOURCC_24BG; -+ case VideoType::kABGR: -+ return libyuv::FOURCC_ABGR; - case VideoType::kRGB565: - return libyuv::FOURCC_RGBP; - case VideoType::kYUY2: -@@ -98,10 +103,16 @@ int ConvertVideoType(VideoType video_type) { +@@ -104,10 +107,16 @@ int ConvertVideoType(VideoType video_type) { return libyuv::FOURCC_UYVY; case VideoType::kMJPEG: return libyuv::FOURCC_MJPG; diff --git a/third_party/libwebrtc/moz-patch-stack/0068.patch b/third_party/libwebrtc/moz-patch-stack/0068.patch index a92343b1d3f1f..05d3466847778 100644 --- a/third_party/libwebrtc/moz-patch-stack/0068.patch +++ b/third_party/libwebrtc/moz-patch-stack/0068.patch @@ -1,23 +1,51 @@ From: Michael Froman -Date: Wed, 13 Jul 2022 12:50:36 -0500 -Subject: Bug 1766646 - (fix-4d12174ca5) add missing include to fix build +Date: Wed, 3 Aug 2022 20:21:25 -0500 +Subject: Bug 1780582 - work around generating VideoFrameBufferType;r=mjf --- - modules/audio_processing/aec3/multi_channel_content_detector.h | 1 + - 1 file changed, 1 insertion(+) + .../api/org/webrtc/VideoFrameBufferType.java | 33 +++++++++++++++++++ + 1 file changed, 33 insertions(+) + create mode 100644 sdk/android/api/org/webrtc/VideoFrameBufferType.java -diff --git a/modules/audio_processing/aec3/multi_channel_content_detector.h b/modules/audio_processing/aec3/multi_channel_content_detector.h -index be8717f3af..1742c5fc17 100644 ---- a/modules/audio_processing/aec3/multi_channel_content_detector.h -+++ b/modules/audio_processing/aec3/multi_channel_content_detector.h -@@ -11,6 +11,7 @@ - #ifndef MODULES_AUDIO_PROCESSING_AEC3_MULTI_CHANNEL_CONTENT_DETECTOR_H_ - #define MODULES_AUDIO_PROCESSING_AEC3_MULTI_CHANNEL_CONTENT_DETECTOR_H_ - -+#include - #include - - #include +diff --git a/sdk/android/api/org/webrtc/VideoFrameBufferType.java b/sdk/android/api/org/webrtc/VideoFrameBufferType.java +new file mode 100644 +index 0000000000..7b05b88cba +--- /dev/null ++++ b/sdk/android/api/org/webrtc/VideoFrameBufferType.java +@@ -0,0 +1,33 @@ ++ ++// Copyright 2022 The Chromium Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++// This file is autogenerated by ++// java_cpp_enum.py ++// From ++// ../../api/video/video_frame_buffer.h ++ ++package org.webrtc; ++ ++import androidx.annotation.IntDef; ++ ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++ ++@IntDef({ ++ VideoFrameBufferType.NATIVE, VideoFrameBufferType.I420, VideoFrameBufferType.I420A, ++ VideoFrameBufferType.I422, VideoFrameBufferType.I444, VideoFrameBufferType.I010, ++ VideoFrameBufferType.I210, VideoFrameBufferType.NV12 ++}) ++@Retention(RetentionPolicy.SOURCE) ++public @interface VideoFrameBufferType { ++ int NATIVE = 0; ++ int I420 = 1; ++ int I420A = 2; ++ int I422 = 3; ++ int I444 = 4; ++ int I010 = 5; ++ int I210 = 6; ++ int NV12 = 7; ++} -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0069.patch b/third_party/libwebrtc/moz-patch-stack/0069.patch index 05d3466847778..39c7c3af5f251 100644 --- a/third_party/libwebrtc/moz-patch-stack/0069.patch +++ b/third_party/libwebrtc/moz-patch-stack/0069.patch @@ -1,51 +1,56 @@ -From: Michael Froman -Date: Wed, 3 Aug 2022 20:21:25 -0500 -Subject: Bug 1780582 - work around generating VideoFrameBufferType;r=mjf +From: Andreas Pehrson +Date: Mon, 5 Sep 2022 13:56:00 +0000 +Subject: Bug 1786502 - Lock access to DeviceInfo devicechange callbacks. + r=webrtc-reviewers,jib +Differential Revision: https://phabricator.services.mozilla.com/D155365 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/e826dfadfe1264c59d9b13e3c17d6f75a40f5c33 --- - .../api/org/webrtc/VideoFrameBufferType.java | 33 +++++++++++++++++++ - 1 file changed, 33 insertions(+) - create mode 100644 sdk/android/api/org/webrtc/VideoFrameBufferType.java + modules/video_capture/video_capture.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) -diff --git a/sdk/android/api/org/webrtc/VideoFrameBufferType.java b/sdk/android/api/org/webrtc/VideoFrameBufferType.java -new file mode 100644 -index 0000000000..7b05b88cba ---- /dev/null -+++ b/sdk/android/api/org/webrtc/VideoFrameBufferType.java -@@ -0,0 +1,33 @@ -+ -+// Copyright 2022 The Chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+// This file is autogenerated by -+// java_cpp_enum.py -+// From -+// ../../api/video/video_frame_buffer.h -+ -+package org.webrtc; -+ -+import androidx.annotation.IntDef; -+ -+import java.lang.annotation.Retention; -+import java.lang.annotation.RetentionPolicy; -+ -+@IntDef({ -+ VideoFrameBufferType.NATIVE, VideoFrameBufferType.I420, VideoFrameBufferType.I420A, -+ VideoFrameBufferType.I422, VideoFrameBufferType.I444, VideoFrameBufferType.I010, -+ VideoFrameBufferType.I210, VideoFrameBufferType.NV12 -+}) -+@Retention(RetentionPolicy.SOURCE) -+public @interface VideoFrameBufferType { -+ int NATIVE = 0; -+ int I420 = 1; -+ int I420A = 2; -+ int I422 = 3; -+ int I444 = 4; -+ int I010 = 5; -+ int I210 = 6; -+ int NV12 = 7; -+} +diff --git a/modules/video_capture/video_capture.h b/modules/video_capture/video_capture.h +index 258bc7f810..ad1b341b62 100644 +--- a/modules/video_capture/video_capture.h ++++ b/modules/video_capture/video_capture.h +@@ -16,6 +16,8 @@ + #include "modules/desktop_capture/desktop_capture_types.h" + #include "modules/video_capture/raw_video_sink_interface.h" + #include "modules/video_capture/video_capture_defines.h" ++#include "rtc_base/synchronization/mutex.h" ++#include "rtc_base/thread_annotations.h" + #include + + #if defined(ANDROID) +@@ -44,15 +46,18 @@ class VideoCaptureModule : public rtc::RefCountInterface { + virtual uint32_t NumberOfDevices() = 0; + virtual int32_t Refresh() = 0; + virtual void DeviceChange() { ++ MutexLock lock(&_inputCallbacksMutex); + for (auto inputCallBack : _inputCallBacks) { + inputCallBack->OnDeviceChange(); + } + } + virtual void RegisterVideoInputFeedBack(VideoInputFeedBack* callBack) { ++ MutexLock lock(&_inputCallbacksMutex); + _inputCallBacks.insert(callBack); + } + + virtual void DeRegisterVideoInputFeedBack(VideoInputFeedBack* callBack) { ++ MutexLock lock(&_inputCallbacksMutex); + auto it = _inputCallBacks.find(callBack); + if (it != _inputCallBacks.end()) { + _inputCallBacks.erase(it); +@@ -106,7 +111,8 @@ class VideoCaptureModule : public rtc::RefCountInterface { + + virtual ~DeviceInfo() {} + private: +- std::set _inputCallBacks; ++ Mutex _inputCallbacksMutex; ++ std::set _inputCallBacks RTC_GUARDED_BY(_inputCallbacksMutex); + }; + + // Register capture data callback -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0070.patch b/third_party/libwebrtc/moz-patch-stack/0070.patch index 39c7c3af5f251..f85d3244f3184 100644 --- a/third_party/libwebrtc/moz-patch-stack/0070.patch +++ b/third_party/libwebrtc/moz-patch-stack/0070.patch @@ -1,56 +1,52 @@ -From: Andreas Pehrson -Date: Mon, 5 Sep 2022 13:56:00 +0000 -Subject: Bug 1786502 - Lock access to DeviceInfo devicechange callbacks. - r=webrtc-reviewers,jib +From: Michael Froman +Date: Mon, 24 Oct 2022 13:00:00 -0500 +Subject: Bug 1797161 - pt1 - tweak BUILD.gn around task_queue_win usage. r?ng! -Differential Revision: https://phabricator.services.mozilla.com/D155365 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/e826dfadfe1264c59d9b13e3c17d6f75a40f5c33 +Add assurance that we will not build task_queue_win.cc to avoid +possible win32k API usage. + +Differential Revision: https://phabricator.services.mozilla.com/D160115 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/f097eb8cbd8b7686ce306a46a4db691194fd39c1 --- - modules/video_capture/video_capture.h | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) + api/task_queue/BUILD.gn | 5 +++++ + rtc_base/BUILD.gn | 4 ++++ + 2 files changed, 9 insertions(+) -diff --git a/modules/video_capture/video_capture.h b/modules/video_capture/video_capture.h -index 258bc7f810..ad1b341b62 100644 ---- a/modules/video_capture/video_capture.h -+++ b/modules/video_capture/video_capture.h -@@ -16,6 +16,8 @@ - #include "modules/desktop_capture/desktop_capture_types.h" - #include "modules/video_capture/raw_video_sink_interface.h" - #include "modules/video_capture/video_capture_defines.h" -+#include "rtc_base/synchronization/mutex.h" -+#include "rtc_base/thread_annotations.h" - #include - - #if defined(ANDROID) -@@ -44,15 +46,18 @@ class VideoCaptureModule : public rtc::RefCountInterface { - virtual uint32_t NumberOfDevices() = 0; - virtual int32_t Refresh() = 0; - virtual void DeviceChange() { -+ MutexLock lock(&_inputCallbacksMutex); - for (auto inputCallBack : _inputCallBacks) { - inputCallBack->OnDeviceChange(); - } - } - virtual void RegisterVideoInputFeedBack(VideoInputFeedBack* callBack) { -+ MutexLock lock(&_inputCallbacksMutex); - _inputCallBacks.insert(callBack); - } - - virtual void DeRegisterVideoInputFeedBack(VideoInputFeedBack* callBack) { -+ MutexLock lock(&_inputCallbacksMutex); - auto it = _inputCallBacks.find(callBack); - if (it != _inputCallBacks.end()) { - _inputCallBacks.erase(it); -@@ -106,7 +111,8 @@ class VideoCaptureModule : public rtc::RefCountInterface { - - virtual ~DeviceInfo() {} - private: -- std::set _inputCallBacks; -+ Mutex _inputCallbacksMutex; -+ std::set _inputCallBacks RTC_GUARDED_BY(_inputCallbacksMutex); - }; +diff --git a/api/task_queue/BUILD.gn b/api/task_queue/BUILD.gn +index 116a50762e..b9c50c1644 100644 +--- a/api/task_queue/BUILD.gn ++++ b/api/task_queue/BUILD.gn +@@ -31,6 +31,11 @@ rtc_library("task_queue") { + ] + } - // Register capture data callback ++# Mozilla - we want to ensure that rtc_include_tests is set to false ++# to guarantee that default_task_queue_factory is not used so we ++# know that remaining win32k code in task_queue_win.cc is not built. ++# See Bug 1797161 for more info. ++assert(!rtc_include_tests, "Mozilla - verify rtc_include_tests is off") + if (rtc_include_tests) { + rtc_library("task_queue_test") { + visibility = [ "*" ] +diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn +index 079d98502e..e474ba8202 100644 +--- a/rtc_base/BUILD.gn ++++ b/rtc_base/BUILD.gn +@@ -694,10 +694,14 @@ if (is_mac || is_ios) { + if (is_win) { + rtc_library("rtc_task_queue_win") { + visibility = [ "../api/task_queue:default_task_queue_factory" ] ++# See Bug 1797161 for more info. Remove from build until win32k ++# usage is removed. ++if (!build_with_mozilla) { + sources = [ + "task_queue_win.cc", + "task_queue_win.h", + ] ++} + deps = [ + ":checks", + ":logging", -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0071.patch b/third_party/libwebrtc/moz-patch-stack/0071.patch index f85d3244f3184..1157ab23d5fd8 100644 --- a/third_party/libwebrtc/moz-patch-stack/0071.patch +++ b/third_party/libwebrtc/moz-patch-stack/0071.patch @@ -1,52 +1,34 @@ From: Michael Froman -Date: Mon, 24 Oct 2022 13:00:00 -0500 -Subject: Bug 1797161 - pt1 - tweak BUILD.gn around task_queue_win usage. r?ng! +Date: Mon, 24 Oct 2022 14:03:00 -0500 +Subject: Bug 1797161 - pt3 - add static_assert to ensure we don't include + task_queue_win.cc in Mozilla builds. r?ng! -Add assurance that we will not build task_queue_win.cc to avoid -possible win32k API usage. - -Differential Revision: https://phabricator.services.mozilla.com/D160115 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/f097eb8cbd8b7686ce306a46a4db691194fd39c1 +Differential Revision: https://phabricator.services.mozilla.com/D160117 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/50b15e036924203147e34ec20e2689fe4a847645 --- - api/task_queue/BUILD.gn | 5 +++++ - rtc_base/BUILD.gn | 4 ++++ - 2 files changed, 9 insertions(+) + rtc_base/task_queue_win.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) -diff --git a/api/task_queue/BUILD.gn b/api/task_queue/BUILD.gn -index 116a50762e..b9c50c1644 100644 ---- a/api/task_queue/BUILD.gn -+++ b/api/task_queue/BUILD.gn -@@ -31,6 +31,11 @@ rtc_library("task_queue") { - ] - } +diff --git a/rtc_base/task_queue_win.cc b/rtc_base/task_queue_win.cc +index 7e46d58e27..bf55a25c69 100644 +--- a/rtc_base/task_queue_win.cc ++++ b/rtc_base/task_queue_win.cc +@@ -8,6 +8,15 @@ + * be found in the AUTHORS file in the root of the source tree. + */ + ++// Mozilla - this file should not be included in Mozilla builds until ++// win32k API usage is removed. This was once done in Bug 1395259, but ++// the upstreaming attempt stalled. Until win32k usage is officially ++// removed upstream, we have reverted to upstream's version of the file ++// (to reduce or elminate merge conflicts), and a static assert is ++// placed here to ensure this file isn't accidentally included in the ++// Mozilla build. ++static_assert(false, "This file should not be built, see Bug 1797161."); ++ + #include "rtc_base/task_queue_win.h" -+# Mozilla - we want to ensure that rtc_include_tests is set to false -+# to guarantee that default_task_queue_factory is not used so we -+# know that remaining win32k code in task_queue_win.cc is not built. -+# See Bug 1797161 for more info. -+assert(!rtc_include_tests, "Mozilla - verify rtc_include_tests is off") - if (rtc_include_tests) { - rtc_library("task_queue_test") { - visibility = [ "*" ] -diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index 079d98502e..e474ba8202 100644 ---- a/rtc_base/BUILD.gn -+++ b/rtc_base/BUILD.gn -@@ -694,10 +694,14 @@ if (is_mac || is_ios) { - if (is_win) { - rtc_library("rtc_task_queue_win") { - visibility = [ "../api/task_queue:default_task_queue_factory" ] -+# See Bug 1797161 for more info. Remove from build until win32k -+# usage is removed. -+if (!build_with_mozilla) { - sources = [ - "task_queue_win.cc", - "task_queue_win.h", - ] -+} - deps = [ - ":checks", - ":logging", + // clang-format off -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0072.patch b/third_party/libwebrtc/moz-patch-stack/0072.patch index 1157ab23d5fd8..94c494c137f20 100644 --- a/third_party/libwebrtc/moz-patch-stack/0072.patch +++ b/third_party/libwebrtc/moz-patch-stack/0072.patch @@ -1,34 +1,81 @@ -From: Michael Froman -Date: Mon, 24 Oct 2022 14:03:00 -0500 -Subject: Bug 1797161 - pt3 - add static_assert to ensure we don't include - task_queue_win.cc in Mozilla builds. r?ng! +From: Andreas Pehrson +Date: Mon, 12 Dec 2022 15:47:00 +0000 +Subject: Bug 1451394 - Expose mac camera capture backend in .gn and switch it + to gecko libyuv. r=webrtc-reviewers,mjf -Differential Revision: https://phabricator.services.mozilla.com/D160117 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/50b15e036924203147e34ec20e2689fe4a847645 +Differential Revision: https://phabricator.services.mozilla.com/D163682 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b0658888969395dca938597783c8a377b9bea209 --- - rtc_base/task_queue_win.cc | 9 +++++++++ - 1 file changed, 9 insertions(+) + BUILD.gn | 4 ++++ + sdk/BUILD.gn | 6 ++++++ + 2 files changed, 10 insertions(+) -diff --git a/rtc_base/task_queue_win.cc b/rtc_base/task_queue_win.cc -index 7e46d58e27..bf55a25c69 100644 ---- a/rtc_base/task_queue_win.cc -+++ b/rtc_base/task_queue_win.cc -@@ -8,6 +8,15 @@ - * be found in the AUTHORS file in the root of the source tree. - */ +diff --git a/BUILD.gn b/BUILD.gn +index b682bdc091..9492870751 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -587,6 +587,10 @@ if (!build_with_chromium) { + ] + } -+// Mozilla - this file should not be included in Mozilla builds until -+// win32k API usage is removed. This was once done in Bug 1395259, but -+// the upstreaming attempt stalled. Until win32k usage is officially -+// removed upstream, we have reverted to upstream's version of the file -+// (to reduce or elminate merge conflicts), and a static assert is -+// placed here to ensure this file isn't accidentally included in the -+// Mozilla build. -+static_assert(false, "This file should not be built, see Bug 1797161."); ++ if (build_with_mozilla && is_mac) { ++ deps += [ "sdk:videocapture_objc" ] ++ } + - #include "rtc_base/task_queue_win.h" + if (rtc_enable_protobuf) { + deps += [ "logging:rtc_event_log_proto" ] + } +diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn +index ff89b21721..bef4521dc6 100644 +--- a/sdk/BUILD.gn ++++ b/sdk/BUILD.gn +@@ -461,6 +461,7 @@ if (is_ios || is_mac) { + } + } - // clang-format off ++ if (!build_with_mozilla) { + rtc_library("videosource_objc") { + sources = [ + "objc/api/peerconnection/RTCVideoSource+Private.h", +@@ -490,6 +491,7 @@ if (is_ios || is_mac) { + ":used_from_extension", + ] + } ++ } + + rtc_library("videoframebuffer_objc") { + visibility = [ "*" ] +@@ -522,6 +524,7 @@ if (is_ios || is_mac) { + ] + } + ++ if (!build_with_mozilla) { + rtc_library("opengl_objc") { + sources = [ + "objc/components/renderer/opengl/RTCDefaultShader.h", +@@ -674,6 +677,7 @@ if (is_ios || is_mac) { + ":videoframebuffer_objc", + ] + } ++ } + + rtc_library("videocapture_objc") { + visibility = [ "*" ] +@@ -702,6 +706,7 @@ if (is_ios || is_mac) { + ] + } + ++ if (!build_with_mozilla) { + rtc_library("videocodec_objc") { + visibility = [ "*" ] + configs += [ "..:no_global_constructors" ] +@@ -1753,5 +1758,6 @@ if (is_ios || is_mac) { + "VideoToolbox.framework", + ] + } ++ } + } + } -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0073.patch b/third_party/libwebrtc/moz-patch-stack/0073.patch index 364b932d30d7e..dba2e9bd7fdb7 100644 --- a/third_party/libwebrtc/moz-patch-stack/0073.patch +++ b/third_party/libwebrtc/moz-patch-stack/0073.patch @@ -1,81 +1,31 @@ From: Andreas Pehrson Date: Mon, 12 Dec 2022 15:47:00 +0000 -Subject: Bug 1451394 - Expose mac camera capture backend in .gn and switch it - to gecko libyuv. r=webrtc-reviewers,mjf +Subject: Bug 1451394 - Record video frame captures with PerformanceRecorder in + the new mac camera backend. r=padenot -Differential Revision: https://phabricator.services.mozilla.com/D163682 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b0658888969395dca938597783c8a377b9bea209 +Also includes: +Bug 1806605 - Pass TrackingId instead of nsCString to CaptureStage. + +Differential Revision: https://phabricator.services.mozilla.com/D163687 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a7362238c9e6fbe0d28200f6b41fc40a0c9a2158 --- - BUILD.gn | 4 ++++ - sdk/BUILD.gn | 6 ++++++ - 2 files changed, 10 insertions(+) + modules/video_capture/video_capture.h | 3 +++ + 1 file changed, 3 insertions(+) -diff --git a/BUILD.gn b/BUILD.gn -index 6b35023104..0f39264f56 100644 ---- a/BUILD.gn -+++ b/BUILD.gn -@@ -574,6 +574,10 @@ if (!build_with_chromium) { - ] - } +diff --git a/modules/video_capture/video_capture.h b/modules/video_capture/video_capture.h +index ad1b341b62..7e181c538e 100644 +--- a/modules/video_capture/video_capture.h ++++ b/modules/video_capture/video_capture.h +@@ -158,6 +158,9 @@ class VideoCaptureModule : public rtc::RefCountInterface { + // Return whether the rotation is applied or left pending. + virtual bool GetApplyRotation() = 0; -+ if (build_with_mozilla && is_mac) { -+ deps += [ "sdk:videocapture_objc" ] -+ } ++ // Mozilla: TrackingId setter for use in profiler markers. ++ virtual void SetTrackingId(uint32_t aTrackingIdProcId) {} + - if (rtc_enable_protobuf) { - deps += [ "logging:rtc_event_log_proto" ] - } -diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn -index 971a323ef5..d8fcb6a61e 100644 ---- a/sdk/BUILD.gn -+++ b/sdk/BUILD.gn -@@ -449,6 +449,7 @@ if (is_ios || is_mac) { - ] - } - -+ if (!build_with_mozilla) { - rtc_library("videosource_objc") { - sources = [ - "objc/api/peerconnection/RTCVideoSource+Private.h", -@@ -478,6 +479,7 @@ if (is_ios || is_mac) { - ":used_from_extension", - ] - } -+ } - - rtc_library("videoframebuffer_objc") { - visibility = [ "*" ] -@@ -510,6 +512,7 @@ if (is_ios || is_mac) { - ] - } - -+ if (!build_with_mozilla) { - rtc_library("opengl_objc") { - sources = [ - "objc/components/renderer/opengl/RTCDefaultShader.h", -@@ -662,6 +665,7 @@ if (is_ios || is_mac) { - ":videoframebuffer_objc", - ] - } -+ } - - rtc_library("videocapture_objc") { - visibility = [ "*" ] -@@ -690,6 +694,7 @@ if (is_ios || is_mac) { - ] - } - -+ if (!build_with_mozilla) { - rtc_library("videocodec_objc") { - visibility = [ "*" ] - configs += [ "..:no_global_constructors" ] -@@ -1740,5 +1745,6 @@ if (is_ios || is_mac) { - "VideoToolbox.framework", - ] - } -+ } - } - } + protected: + ~VideoCaptureModule() override {} + }; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0074.patch b/third_party/libwebrtc/moz-patch-stack/0074.patch index dba2e9bd7fdb7..7b7d7abdf831d 100644 --- a/third_party/libwebrtc/moz-patch-stack/0074.patch +++ b/third_party/libwebrtc/moz-patch-stack/0074.patch @@ -1,31 +1,346 @@ From: Andreas Pehrson -Date: Mon, 12 Dec 2022 15:47:00 +0000 -Subject: Bug 1451394 - Record video frame captures with PerformanceRecorder in - the new mac camera backend. r=padenot +Date: Tue, 23 Nov 2021 14:11:00 +0000 +Subject: Bug 1742181 - libwebrtc: Implement packetsDiscarded bookkeeping for + received video. r=ng + +Depends on D131707 + +Differential Revision: https://phabricator.services.mozilla.com/D131708 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d0196a45a1f449874fc2a759e85e403c45c25575 Also includes: -Bug 1806605 - Pass TrackingId instead of nsCString to CaptureStage. -Differential Revision: https://phabricator.services.mozilla.com/D163687 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a7362238c9e6fbe0d28200f6b41fc40a0c9a2158 +Bug 1804288 - (fix-de7ae5755b) reimplement Bug 1742181 - libwebrtc: Implement packetsDiscarded bookkeeping for received video. r=pehrsons + +Differential Revision: https://phabricator.services.mozilla.com/D163959 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/ee566d1bfb654d36e5d58dce637fb0580b989ac1 --- - modules/video_capture/video_capture.h | 3 +++ - 1 file changed, 3 insertions(+) + api/video/frame_buffer.cc | 25 ++++++++++++++++--- + api/video/frame_buffer.h | 4 +++ + call/video_receive_stream.h | 2 ++ + .../include/video_coding_defines.h | 2 ++ + modules/video_coding/packet_buffer.cc | 10 +++++--- + modules/video_coding/packet_buffer.h | 5 +++- + video/receive_statistics_proxy2.cc | 5 ++++ + video/receive_statistics_proxy2.h | 1 + + video/rtp_video_stream_receiver2.cc | 5 +++- + video/rtp_video_stream_receiver2.h | 2 ++ + video/video_receive_stream2.cc | 1 + + video/video_stream_buffer_controller.cc | 12 +++++++++ + video/video_stream_buffer_controller.h | 3 +++ + 13 files changed, 69 insertions(+), 8 deletions(-) -diff --git a/modules/video_capture/video_capture.h b/modules/video_capture/video_capture.h -index ad1b341b62..7e181c538e 100644 ---- a/modules/video_capture/video_capture.h -+++ b/modules/video_capture/video_capture.h -@@ -158,6 +158,9 @@ class VideoCaptureModule : public rtc::RefCountInterface { - // Return whether the rotation is applied or left pending. - virtual bool GetApplyRotation() = 0; - -+ // Mozilla: TrackingId setter for use in profiler markers. -+ virtual void SetTrackingId(uint32_t aTrackingIdProcId) {} -+ - protected: - ~VideoCaptureModule() override {} +diff --git a/api/video/frame_buffer.cc b/api/video/frame_buffer.cc +index 4cdf2212a6..8267b8e6cb 100644 +--- a/api/video/frame_buffer.cc ++++ b/api/video/frame_buffer.cc +@@ -140,14 +140,29 @@ void FrameBuffer::DropNextDecodableTemporalUnit() { + } + + auto end_it = std::next(next_decodable_temporal_unit_->last_frame); +- num_dropped_frames_ += std::count_if( +- frames_.begin(), end_it, +- [](const auto& f) { return f.second.encoded_frame != nullptr; }); ++ ++ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), end_it); + + frames_.erase(frames_.begin(), end_it); + FindNextAndLastDecodableTemporalUnit(); + } + ++void FrameBuffer::UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, ++ FrameIterator end_it) { ++ unsigned int num_discarded_packets = 0; ++ unsigned int num_dropped_frames = ++ std::count_if(begin_it, end_it, [&](const auto& f) { ++ if (f.second.encoded_frame) { ++ const auto& packetInfos = f.second.encoded_frame->PacketInfos(); ++ num_discarded_packets += packetInfos.size(); ++ } ++ return f.second.encoded_frame != nullptr; ++ }); ++ ++ num_dropped_frames_ += num_dropped_frames; ++ num_discarded_packets_ += num_discarded_packets; ++} ++ + absl::optional FrameBuffer::LastContinuousFrameId() const { + return last_continuous_frame_id_; + } +@@ -167,6 +182,9 @@ int FrameBuffer::GetTotalNumberOfContinuousTemporalUnits() const { + int FrameBuffer::GetTotalNumberOfDroppedFrames() const { + return num_dropped_frames_; + } ++int FrameBuffer::GetTotalNumberOfDiscardedPackets() const { ++ return num_discarded_packets_; ++} + + size_t FrameBuffer::CurrentSize() const { + return frames_.size(); +@@ -269,6 +287,7 @@ void FrameBuffer::FindNextAndLastDecodableTemporalUnit() { + } + + void FrameBuffer::Clear() { ++ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), frames_.end()); + frames_.clear(); + next_decodable_temporal_unit_.reset(); + decodable_temporal_units_info_.reset(); +diff --git a/api/video/frame_buffer.h b/api/video/frame_buffer.h +index 94edf64d5a..81fd12da58 100644 +--- a/api/video/frame_buffer.h ++++ b/api/video/frame_buffer.h +@@ -66,6 +66,7 @@ class FrameBuffer { + + int GetTotalNumberOfContinuousTemporalUnits() const; + int GetTotalNumberOfDroppedFrames() const; ++ int GetTotalNumberOfDiscardedPackets() const; + size_t CurrentSize() const; + + private: +@@ -87,6 +88,8 @@ class FrameBuffer { + void PropagateContinuity(const FrameIterator& frame_it); + void FindNextAndLastDecodableTemporalUnit(); + void Clear(); ++ void UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, ++ FrameIterator end_it); + + const bool legacy_frame_id_jump_behavior_; + const size_t max_size_; +@@ -99,6 +102,7 @@ class FrameBuffer { + + int num_continuous_temporal_units_ = 0; + int num_dropped_frames_ = 0; ++ int num_discarded_packets_ = 0; }; + + } // namespace webrtc +diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h +index 18b8a71e3c..9ef1a9b53e 100644 +--- a/call/video_receive_stream.h ++++ b/call/video_receive_stream.h +@@ -108,6 +108,8 @@ class VideoReceiveStreamInterface : public MediaReceiveStreamInterface { + // https://www.w3.org/TR/webrtc-stats/#dom-rtcvideoreceiverstats-framesdropped + uint32_t frames_dropped = 0; + uint32_t frames_decoded = 0; ++ // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsdiscarded ++ uint64_t packets_discarded = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime + TimeDelta total_decode_time = TimeDelta::Zero(); + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay +diff --git a/modules/video_coding/include/video_coding_defines.h b/modules/video_coding/include/video_coding_defines.h +index 8f70e0298d..bf98d5e668 100644 +--- a/modules/video_coding/include/video_coding_defines.h ++++ b/modules/video_coding/include/video_coding_defines.h +@@ -76,6 +76,8 @@ class VCMReceiveStatisticsCallback { + + virtual void OnDroppedFrames(uint32_t frames_dropped) = 0; + ++ virtual void OnDiscardedPackets(uint32_t packets_discarded) = 0; ++ + virtual void OnFrameBufferTimingsUpdated(int max_decode_ms, + int current_delay_ms, + int target_delay_ms, +diff --git a/modules/video_coding/packet_buffer.cc b/modules/video_coding/packet_buffer.cc +index 52ef5c2d85..be45db6ef0 100644 +--- a/modules/video_coding/packet_buffer.cc ++++ b/modules/video_coding/packet_buffer.cc +@@ -115,25 +115,27 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket( + return result; + } + +-void PacketBuffer::ClearTo(uint16_t seq_num) { ++uint32_t PacketBuffer::ClearTo(uint16_t seq_num) { + // We have already cleared past this sequence number, no need to do anything. + if (is_cleared_to_first_seq_num_ && + AheadOf(first_seq_num_, seq_num)) { +- return; ++ return 0; + } + + // If the packet buffer was cleared between a frame was created and returned. + if (!first_packet_received_) +- return; ++ return 0; + + // Avoid iterating over the buffer more than once by capping the number of + // iterations to the `size_` of the buffer. + ++seq_num; ++ uint32_t num_cleared_packets = 0; + size_t diff = ForwardDiff(first_seq_num_, seq_num); + size_t iterations = std::min(diff, buffer_.size()); + for (size_t i = 0; i < iterations; ++i) { + auto& stored = buffer_[first_seq_num_ % buffer_.size()]; + if (stored != nullptr && AheadOf(seq_num, stored->seq_num)) { ++ ++num_cleared_packets; + stored = nullptr; + } + ++first_seq_num_; +@@ -149,6 +151,8 @@ void PacketBuffer::ClearTo(uint16_t seq_num) { + + received_padding_.erase(received_padding_.begin(), + received_padding_.lower_bound(seq_num)); ++ ++ return num_cleared_packets; + } + + void PacketBuffer::Clear() { +diff --git a/modules/video_coding/packet_buffer.h b/modules/video_coding/packet_buffer.h +index 53e08c95a1..47b2ffe199 100644 +--- a/modules/video_coding/packet_buffer.h ++++ b/modules/video_coding/packet_buffer.h +@@ -78,7 +78,10 @@ class PacketBuffer { + ABSL_MUST_USE_RESULT InsertResult + InsertPacket(std::unique_ptr packet); + ABSL_MUST_USE_RESULT InsertResult InsertPadding(uint16_t seq_num); +- void ClearTo(uint16_t seq_num); ++ ++ // Clear all packets older than |seq_num|. Returns the number of packets ++ // cleared. ++ uint32_t ClearTo(uint16_t seq_num); + void Clear(); + + void ForceSpsPpsIdrIsH264Keyframe(); +diff --git a/video/receive_statistics_proxy2.cc b/video/receive_statistics_proxy2.cc +index 4f208a1d5e..020e4bb0ae 100644 +--- a/video/receive_statistics_proxy2.cc ++++ b/video/receive_statistics_proxy2.cc +@@ -959,6 +959,11 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { + })); + } + ++void ReceiveStatisticsProxy::OnDiscardedPackets(uint32_t packets_discarded) { ++ RTC_DCHECK_RUN_ON(&main_thread_); ++ stats_.packets_discarded += packets_discarded; ++} ++ + void ReceiveStatisticsProxy::OnPreDecode(VideoCodecType codec_type, int qp) { + RTC_DCHECK_RUN_ON(&main_thread_); + last_codec_type_ = codec_type; +diff --git a/video/receive_statistics_proxy2.h b/video/receive_statistics_proxy2.h +index 1a2bb77fa6..20139b45e5 100644 +--- a/video/receive_statistics_proxy2.h ++++ b/video/receive_statistics_proxy2.h +@@ -90,6 +90,7 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback, + size_t size_bytes, + VideoContentType content_type) override; + void OnDroppedFrames(uint32_t frames_dropped) override; ++ void OnDiscardedPackets(uint32_t packets_discarded) override; + void OnFrameBufferTimingsUpdated(int max_decode_ms, + int current_delay_ms, + int target_delay_ms, +diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc +index 5dd234c1bf..993745ba9d 100644 +--- a/video/rtp_video_stream_receiver2.cc ++++ b/video/rtp_video_stream_receiver2.cc +@@ -244,6 +244,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( + RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, + RtcpCnameCallback* rtcp_cname_callback, + NackPeriodicProcessor* nack_periodic_processor, ++ VCMReceiveStatisticsCallback* vcm_receive_statistics, + OnCompleteFrameCallback* complete_frame_callback, + rtc::scoped_refptr frame_decryptor, + rtc::scoped_refptr frame_transformer, +@@ -292,6 +293,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( + &rtcp_feedback_buffer_, + &rtcp_feedback_buffer_, + field_trials_)), ++ vcm_receive_statistics_(vcm_receive_statistics), + packet_buffer_(kPacketBufferStartSize, + PacketBufferMaxSize(field_trials_)), + reference_finder_(std::make_unique()), +@@ -1206,7 +1208,8 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { + int64_t unwrapped_rtp_seq_num = rtp_seq_num_unwrapper_.Unwrap(seq_num); + packet_infos_.erase(packet_infos_.begin(), + packet_infos_.upper_bound(unwrapped_rtp_seq_num)); +- packet_buffer_.ClearTo(seq_num); ++ uint32_t num_packets_cleared = packet_buffer_.ClearTo(seq_num); ++ vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); + reference_finder_->ClearTo(seq_num); + } + } +diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h +index dc9cea422d..90bce6d4b5 100644 +--- a/video/rtp_video_stream_receiver2.h ++++ b/video/rtp_video_stream_receiver2.h +@@ -91,6 +91,7 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, + RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, + RtcpCnameCallback* rtcp_cname_callback, + NackPeriodicProcessor* nack_periodic_processor, ++ VCMReceiveStatisticsCallback* vcm_receive_statistics, + // The KeyFrameRequestSender is optional; if not provided, key frame + // requests are sent via the internal RtpRtcp module. + OnCompleteFrameCallback* complete_frame_callback, +@@ -361,6 +362,7 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, + std::unique_ptr loss_notification_controller_ + RTC_GUARDED_BY(packet_sequence_checker_); + ++ VCMReceiveStatisticsCallback* const vcm_receive_statistics_; + video_coding::PacketBuffer packet_buffer_ + RTC_GUARDED_BY(packet_sequence_checker_); + UniqueTimestampCounter frame_counter_ +diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc +index ea250ec321..5bad053c36 100644 +--- a/video/video_receive_stream2.cc ++++ b/video/video_receive_stream2.cc +@@ -211,6 +211,7 @@ VideoReceiveStream2::VideoReceiveStream2( + &stats_proxy_, + &stats_proxy_, + nack_periodic_processor, ++ &stats_proxy_, + this, // OnCompleteFrameCallback + std::move(config_.frame_decryptor), + std::move(config_.frame_transformer), +diff --git a/video/video_stream_buffer_controller.cc b/video/video_stream_buffer_controller.cc +index c95fb7d64d..cc2b7854cf 100644 +--- a/video/video_stream_buffer_controller.cc ++++ b/video/video_stream_buffer_controller.cc +@@ -250,6 +250,7 @@ void VideoStreamBufferController::OnFrameReady( + + // Update stats. + UpdateDroppedFrames(); ++ UpdateDiscardedPackets(); + UpdateJitterDelay(); + UpdateTimingFrameInfo(); + +@@ -315,6 +316,17 @@ void VideoStreamBufferController::UpdateDroppedFrames() + buffer_->GetTotalNumberOfDroppedFrames(); + } + ++void VideoStreamBufferController::UpdateDiscardedPackets() ++ RTC_RUN_ON(&worker_sequence_checker_) { ++ const int discarded_packets = buffer_->GetTotalNumberOfDiscardedPackets() - ++ packets_discarded_before_last_new_frame_; ++ if (discarded_packets > 0) { ++ stats_proxy_->OnDiscardedPackets(discarded_packets); ++ } ++ packets_discarded_before_last_new_frame_ = ++ buffer_->GetTotalNumberOfDiscardedPackets(); ++} ++ + void VideoStreamBufferController::UpdateJitterDelay() { + auto timings = timing_->GetTimings(); + if (timings.num_decoded_frames) { +diff --git a/video/video_stream_buffer_controller.h b/video/video_stream_buffer_controller.h +index 85852d5398..a700a619a7 100644 +--- a/video/video_stream_buffer_controller.h ++++ b/video/video_stream_buffer_controller.h +@@ -67,6 +67,7 @@ class VideoStreamBufferController { + void OnTimeout(TimeDelta delay); + void FrameReadyForDecode(uint32_t rtp_timestamp, Timestamp render_time); + void UpdateDroppedFrames() RTC_RUN_ON(&worker_sequence_checker_); ++ void UpdateDiscardedPackets() RTC_RUN_ON(&worker_sequence_checker_); + void UpdateJitterDelay(); + void UpdateTimingFrameInfo(); + bool IsTooManyFramesQueued() const RTC_RUN_ON(&worker_sequence_checker_); +@@ -95,6 +96,8 @@ class VideoStreamBufferController { + RTC_GUARDED_BY(&worker_sequence_checker_); + int frames_dropped_before_last_new_frame_ + RTC_GUARDED_BY(&worker_sequence_checker_) = 0; ++ int packets_discarded_before_last_new_frame_ ++ RTC_GUARDED_BY(&worker_sequence_checker_) = 0; + VCMVideoProtection protection_mode_ + RTC_GUARDED_BY(&worker_sequence_checker_) = kProtectionNack; + -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0075.patch b/third_party/libwebrtc/moz-patch-stack/0075.patch index eeec2ebde6d03..1acfa4f89d595 100644 --- a/third_party/libwebrtc/moz-patch-stack/0075.patch +++ b/third_party/libwebrtc/moz-patch-stack/0075.patch @@ -1,346 +1,49 @@ From: Andreas Pehrson -Date: Tue, 23 Nov 2021 14:11:00 +0000 -Subject: Bug 1742181 - libwebrtc: Implement packetsDiscarded bookkeeping for - received video. r=ng +Date: Thu, 6 Jan 2022 00:16:00 +0000 +Subject: Bug 1748478 - Propagate calculated discarded packets to stats. r=bwc -Depends on D131707 - -Differential Revision: https://phabricator.services.mozilla.com/D131708 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d0196a45a1f449874fc2a759e85e403c45c25575 - -Also includes: - -Bug 1804288 - (fix-de7ae5755b) reimplement Bug 1742181 - libwebrtc: Implement packetsDiscarded bookkeeping for received video. r=pehrsons - -Differential Revision: https://phabricator.services.mozilla.com/D163959 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/ee566d1bfb654d36e5d58dce637fb0580b989ac1 +Differential Revision: https://phabricator.services.mozilla.com/D135061 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/56fbf0469e25fa0d589c51ca112ce534a7c0ab91 --- - api/video/frame_buffer.cc | 25 ++++++++++++++++--- - api/video/frame_buffer.h | 4 +++ - call/video_receive_stream.h | 2 ++ - .../include/video_coding_defines.h | 2 ++ - modules/video_coding/packet_buffer.cc | 10 +++++--- - modules/video_coding/packet_buffer.h | 5 +++- - video/receive_statistics_proxy2.cc | 5 ++++ - video/receive_statistics_proxy2.h | 1 + - video/rtp_video_stream_receiver2.cc | 5 +++- - video/rtp_video_stream_receiver2.h | 2 ++ - video/video_receive_stream2.cc | 1 + - video/video_stream_buffer_controller.cc | 12 +++++++++ - video/video_stream_buffer_controller.h | 3 +++ - 13 files changed, 69 insertions(+), 8 deletions(-) + video/receive_statistics_proxy2.cc | 9 +++++++-- + video/rtp_video_stream_receiver2.cc | 4 +++- + 2 files changed, 10 insertions(+), 3 deletions(-) -diff --git a/api/video/frame_buffer.cc b/api/video/frame_buffer.cc -index 4cdf2212a6..8267b8e6cb 100644 ---- a/api/video/frame_buffer.cc -+++ b/api/video/frame_buffer.cc -@@ -140,14 +140,29 @@ void FrameBuffer::DropNextDecodableTemporalUnit() { - } - - auto end_it = std::next(next_decodable_temporal_unit_->last_frame); -- num_dropped_frames_ += std::count_if( -- frames_.begin(), end_it, -- [](const auto& f) { return f.second.encoded_frame != nullptr; }); -+ -+ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), end_it); - - frames_.erase(frames_.begin(), end_it); - FindNextAndLastDecodableTemporalUnit(); - } - -+void FrameBuffer::UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, -+ FrameIterator end_it) { -+ unsigned int num_discarded_packets = 0; -+ unsigned int num_dropped_frames = -+ std::count_if(begin_it, end_it, [&](const auto& f) { -+ if (f.second.encoded_frame) { -+ const auto& packetInfos = f.second.encoded_frame->PacketInfos(); -+ num_discarded_packets += packetInfos.size(); -+ } -+ return f.second.encoded_frame != nullptr; -+ }); -+ -+ num_dropped_frames_ += num_dropped_frames; -+ num_discarded_packets_ += num_discarded_packets; -+} -+ - absl::optional FrameBuffer::LastContinuousFrameId() const { - return last_continuous_frame_id_; - } -@@ -167,6 +182,9 @@ int FrameBuffer::GetTotalNumberOfContinuousTemporalUnits() const { - int FrameBuffer::GetTotalNumberOfDroppedFrames() const { - return num_dropped_frames_; - } -+int FrameBuffer::GetTotalNumberOfDiscardedPackets() const { -+ return num_discarded_packets_; -+} - - size_t FrameBuffer::CurrentSize() const { - return frames_.size(); -@@ -269,6 +287,7 @@ void FrameBuffer::FindNextAndLastDecodableTemporalUnit() { - } - - void FrameBuffer::Clear() { -+ UpdateDroppedFramesAndDiscardedPackets(frames_.begin(), frames_.end()); - frames_.clear(); - next_decodable_temporal_unit_.reset(); - decodable_temporal_units_info_.reset(); -diff --git a/api/video/frame_buffer.h b/api/video/frame_buffer.h -index 94edf64d5a..81fd12da58 100644 ---- a/api/video/frame_buffer.h -+++ b/api/video/frame_buffer.h -@@ -66,6 +66,7 @@ class FrameBuffer { - - int GetTotalNumberOfContinuousTemporalUnits() const; - int GetTotalNumberOfDroppedFrames() const; -+ int GetTotalNumberOfDiscardedPackets() const; - size_t CurrentSize() const; - - private: -@@ -87,6 +88,8 @@ class FrameBuffer { - void PropagateContinuity(const FrameIterator& frame_it); - void FindNextAndLastDecodableTemporalUnit(); - void Clear(); -+ void UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, -+ FrameIterator end_it); - - const bool legacy_frame_id_jump_behavior_; - const size_t max_size_; -@@ -99,6 +102,7 @@ class FrameBuffer { - - int num_continuous_temporal_units_ = 0; - int num_dropped_frames_ = 0; -+ int num_discarded_packets_ = 0; - }; - - } // namespace webrtc -diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h -index 18b8a71e3c..9ef1a9b53e 100644 ---- a/call/video_receive_stream.h -+++ b/call/video_receive_stream.h -@@ -108,6 +108,8 @@ class VideoReceiveStreamInterface : public MediaReceiveStreamInterface { - // https://www.w3.org/TR/webrtc-stats/#dom-rtcvideoreceiverstats-framesdropped - uint32_t frames_dropped = 0; - uint32_t frames_decoded = 0; -+ // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsdiscarded -+ uint64_t packets_discarded = 0; - // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime - TimeDelta total_decode_time = TimeDelta::Zero(); - // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay -diff --git a/modules/video_coding/include/video_coding_defines.h b/modules/video_coding/include/video_coding_defines.h -index 8f70e0298d..bf98d5e668 100644 ---- a/modules/video_coding/include/video_coding_defines.h -+++ b/modules/video_coding/include/video_coding_defines.h -@@ -76,6 +76,8 @@ class VCMReceiveStatisticsCallback { - - virtual void OnDroppedFrames(uint32_t frames_dropped) = 0; - -+ virtual void OnDiscardedPackets(uint32_t packets_discarded) = 0; -+ - virtual void OnFrameBufferTimingsUpdated(int max_decode_ms, - int current_delay_ms, - int target_delay_ms, -diff --git a/modules/video_coding/packet_buffer.cc b/modules/video_coding/packet_buffer.cc -index 9a599cd4bd..9f1bb211c5 100644 ---- a/modules/video_coding/packet_buffer.cc -+++ b/modules/video_coding/packet_buffer.cc -@@ -115,25 +115,27 @@ PacketBuffer::InsertResult PacketBuffer::InsertPacket( - return result; - } - --void PacketBuffer::ClearTo(uint16_t seq_num) { -+uint32_t PacketBuffer::ClearTo(uint16_t seq_num) { - // We have already cleared past this sequence number, no need to do anything. - if (is_cleared_to_first_seq_num_ && - AheadOf(first_seq_num_, seq_num)) { -- return; -+ return 0; - } - - // If the packet buffer was cleared between a frame was created and returned. - if (!first_packet_received_) -- return; -+ return 0; - - // Avoid iterating over the buffer more than once by capping the number of - // iterations to the `size_` of the buffer. - ++seq_num; -+ uint32_t num_cleared_packets = 0; - size_t diff = ForwardDiff(first_seq_num_, seq_num); - size_t iterations = std::min(diff, buffer_.size()); - for (size_t i = 0; i < iterations; ++i) { - auto& stored = buffer_[first_seq_num_ % buffer_.size()]; - if (stored != nullptr && AheadOf(seq_num, stored->seq_num)) { -+ ++num_cleared_packets; - stored = nullptr; - } - ++first_seq_num_; -@@ -149,6 +151,8 @@ void PacketBuffer::ClearTo(uint16_t seq_num) { - - received_padding_.erase(received_padding_.begin(), - received_padding_.lower_bound(seq_num)); -+ -+ return num_cleared_packets; - } - - void PacketBuffer::Clear() { -diff --git a/modules/video_coding/packet_buffer.h b/modules/video_coding/packet_buffer.h -index 53e08c95a1..47b2ffe199 100644 ---- a/modules/video_coding/packet_buffer.h -+++ b/modules/video_coding/packet_buffer.h -@@ -78,7 +78,10 @@ class PacketBuffer { - ABSL_MUST_USE_RESULT InsertResult - InsertPacket(std::unique_ptr packet); - ABSL_MUST_USE_RESULT InsertResult InsertPadding(uint16_t seq_num); -- void ClearTo(uint16_t seq_num); -+ -+ // Clear all packets older than |seq_num|. Returns the number of packets -+ // cleared. -+ uint32_t ClearTo(uint16_t seq_num); - void Clear(); - - void ForceSpsPpsIdrIsH264Keyframe(); diff --git a/video/receive_statistics_proxy2.cc b/video/receive_statistics_proxy2.cc -index 4f208a1d5e..020e4bb0ae 100644 +index 020e4bb0ae..f5011c46ef 100644 --- a/video/receive_statistics_proxy2.cc +++ b/video/receive_statistics_proxy2.cc -@@ -959,6 +959,11 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { - })); +@@ -960,8 +960,13 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { + } + + void ReceiveStatisticsProxy::OnDiscardedPackets(uint32_t packets_discarded) { +- RTC_DCHECK_RUN_ON(&main_thread_); +- stats_.packets_discarded += packets_discarded; ++ // Can be called on either the decode queue or the worker thread ++ // See FrameBuffer2 for more details. ++ worker_thread_->PostTask( ++ SafeTask(task_safety_.flag(), [packets_discarded, this]() { ++ RTC_DCHECK_RUN_ON(&main_thread_); ++ stats_.packets_discarded += packets_discarded; ++ })); } -+void ReceiveStatisticsProxy::OnDiscardedPackets(uint32_t packets_discarded) { -+ RTC_DCHECK_RUN_ON(&main_thread_); -+ stats_.packets_discarded += packets_discarded; -+} -+ void ReceiveStatisticsProxy::OnPreDecode(VideoCodecType codec_type, int qp) { - RTC_DCHECK_RUN_ON(&main_thread_); - last_codec_type_ = codec_type; -diff --git a/video/receive_statistics_proxy2.h b/video/receive_statistics_proxy2.h -index 1a2bb77fa6..20139b45e5 100644 ---- a/video/receive_statistics_proxy2.h -+++ b/video/receive_statistics_proxy2.h -@@ -90,6 +90,7 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback, - size_t size_bytes, - VideoContentType content_type) override; - void OnDroppedFrames(uint32_t frames_dropped) override; -+ void OnDiscardedPackets(uint32_t packets_discarded) override; - void OnFrameBufferTimingsUpdated(int max_decode_ms, - int current_delay_ms, - int target_delay_ms, diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc -index 5dd234c1bf..993745ba9d 100644 +index 993745ba9d..289c8990bb 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc -@@ -244,6 +244,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( - RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, - RtcpCnameCallback* rtcp_cname_callback, - NackPeriodicProcessor* nack_periodic_processor, -+ VCMReceiveStatisticsCallback* vcm_receive_statistics, - OnCompleteFrameCallback* complete_frame_callback, - rtc::scoped_refptr frame_decryptor, - rtc::scoped_refptr frame_transformer, -@@ -292,6 +293,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( - &rtcp_feedback_buffer_, - &rtcp_feedback_buffer_, - field_trials_)), -+ vcm_receive_statistics_(vcm_receive_statistics), - packet_buffer_(kPacketBufferStartSize, - PacketBufferMaxSize(field_trials_)), - reference_finder_(std::make_unique()), -@@ -1206,7 +1208,8 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { - int64_t unwrapped_rtp_seq_num = rtp_seq_num_unwrapper_.Unwrap(seq_num); +@@ -1209,7 +1209,9 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { packet_infos_.erase(packet_infos_.begin(), packet_infos_.upper_bound(unwrapped_rtp_seq_num)); -- packet_buffer_.ClearTo(seq_num); -+ uint32_t num_packets_cleared = packet_buffer_.ClearTo(seq_num); -+ vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); + uint32_t num_packets_cleared = packet_buffer_.ClearTo(seq_num); +- vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); ++ if (num_packets_cleared > 0) { ++ vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); ++ } reference_finder_->ClearTo(seq_num); } } -diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h -index dc9cea422d..90bce6d4b5 100644 ---- a/video/rtp_video_stream_receiver2.h -+++ b/video/rtp_video_stream_receiver2.h -@@ -91,6 +91,7 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, - RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer, - RtcpCnameCallback* rtcp_cname_callback, - NackPeriodicProcessor* nack_periodic_processor, -+ VCMReceiveStatisticsCallback* vcm_receive_statistics, - // The KeyFrameRequestSender is optional; if not provided, key frame - // requests are sent via the internal RtpRtcp module. - OnCompleteFrameCallback* complete_frame_callback, -@@ -361,6 +362,7 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, - std::unique_ptr loss_notification_controller_ - RTC_GUARDED_BY(packet_sequence_checker_); - -+ VCMReceiveStatisticsCallback* const vcm_receive_statistics_; - video_coding::PacketBuffer packet_buffer_ - RTC_GUARDED_BY(packet_sequence_checker_); - UniqueTimestampCounter frame_counter_ -diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc -index ea250ec321..5bad053c36 100644 ---- a/video/video_receive_stream2.cc -+++ b/video/video_receive_stream2.cc -@@ -211,6 +211,7 @@ VideoReceiveStream2::VideoReceiveStream2( - &stats_proxy_, - &stats_proxy_, - nack_periodic_processor, -+ &stats_proxy_, - this, // OnCompleteFrameCallback - std::move(config_.frame_decryptor), - std::move(config_.frame_transformer), -diff --git a/video/video_stream_buffer_controller.cc b/video/video_stream_buffer_controller.cc -index c95fb7d64d..cc2b7854cf 100644 ---- a/video/video_stream_buffer_controller.cc -+++ b/video/video_stream_buffer_controller.cc -@@ -250,6 +250,7 @@ void VideoStreamBufferController::OnFrameReady( - - // Update stats. - UpdateDroppedFrames(); -+ UpdateDiscardedPackets(); - UpdateJitterDelay(); - UpdateTimingFrameInfo(); - -@@ -315,6 +316,17 @@ void VideoStreamBufferController::UpdateDroppedFrames() - buffer_->GetTotalNumberOfDroppedFrames(); - } - -+void VideoStreamBufferController::UpdateDiscardedPackets() -+ RTC_RUN_ON(&worker_sequence_checker_) { -+ const int discarded_packets = buffer_->GetTotalNumberOfDiscardedPackets() - -+ packets_discarded_before_last_new_frame_; -+ if (discarded_packets > 0) { -+ stats_proxy_->OnDiscardedPackets(discarded_packets); -+ } -+ packets_discarded_before_last_new_frame_ = -+ buffer_->GetTotalNumberOfDiscardedPackets(); -+} -+ - void VideoStreamBufferController::UpdateJitterDelay() { - auto timings = timing_->GetTimings(); - if (timings.num_decoded_frames) { -diff --git a/video/video_stream_buffer_controller.h b/video/video_stream_buffer_controller.h -index 85852d5398..a700a619a7 100644 ---- a/video/video_stream_buffer_controller.h -+++ b/video/video_stream_buffer_controller.h -@@ -67,6 +67,7 @@ class VideoStreamBufferController { - void OnTimeout(TimeDelta delay); - void FrameReadyForDecode(uint32_t rtp_timestamp, Timestamp render_time); - void UpdateDroppedFrames() RTC_RUN_ON(&worker_sequence_checker_); -+ void UpdateDiscardedPackets() RTC_RUN_ON(&worker_sequence_checker_); - void UpdateJitterDelay(); - void UpdateTimingFrameInfo(); - bool IsTooManyFramesQueued() const RTC_RUN_ON(&worker_sequence_checker_); -@@ -95,6 +96,8 @@ class VideoStreamBufferController { - RTC_GUARDED_BY(&worker_sequence_checker_); - int frames_dropped_before_last_new_frame_ - RTC_GUARDED_BY(&worker_sequence_checker_) = 0; -+ int packets_discarded_before_last_new_frame_ -+ RTC_GUARDED_BY(&worker_sequence_checker_) = 0; - VCMVideoProtection protection_mode_ - RTC_GUARDED_BY(&worker_sequence_checker_) = kProtectionNack; - -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0076.patch b/third_party/libwebrtc/moz-patch-stack/0076.patch index 1acfa4f89d595..d38c60059246f 100644 --- a/third_party/libwebrtc/moz-patch-stack/0076.patch +++ b/third_party/libwebrtc/moz-patch-stack/0076.patch @@ -1,49 +1,224 @@ From: Andreas Pehrson Date: Thu, 6 Jan 2022 00:16:00 +0000 -Subject: Bug 1748478 - Propagate calculated discarded packets to stats. r=bwc +Subject: Bug 1748458 - Add TRACE_EVENTs for dropped frames and packets for + received video. r=bwc -Differential Revision: https://phabricator.services.mozilla.com/D135061 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/56fbf0469e25fa0d589c51ca112ce534a7c0ab91 +This lets us see in the profiler how many received frames and packets we decide +to drop and the reasons why. + +Differential Revision: https://phabricator.services.mozilla.com/D135062 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/08e252da94c4752eccfd845eef13d8517953cc6a + +Also includes: + +Bug 1804288 - (fix-de7ae5755b) reimplement Bug 1748458 - Add TRACE_EVENTs for dropped frames and packets for received video. r=pehrsons + +Differential Revision: https://phabricator.services.mozilla.com/D163960 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8e9a326a99cd5eaa6e447ff57c01ad9d79a09744 --- - video/receive_statistics_proxy2.cc | 9 +++++++-- - video/rtp_video_stream_receiver2.cc | 4 +++- - 2 files changed, 10 insertions(+), 3 deletions(-) + api/video/frame_buffer.cc | 33 +++++++++++++++++++++++++ + video/receive_statistics_proxy2.cc | 11 +++++++++ + video/rtp_video_stream_receiver2.cc | 4 +++ + video/video_stream_buffer_controller.cc | 7 ++++++ + 4 files changed, 55 insertions(+) +diff --git a/api/video/frame_buffer.cc b/api/video/frame_buffer.cc +index 8267b8e6cb..f5d93f5f76 100644 +--- a/api/video/frame_buffer.cc ++++ b/api/video/frame_buffer.cc +@@ -16,6 +16,7 @@ + #include "absl/container/inlined_vector.h" + #include "rtc_base/logging.h" + #include "rtc_base/numerics/sequence_number_util.h" ++#include "rtc_base/trace_event.h" + + namespace webrtc { + namespace { +@@ -68,7 +69,12 @@ FrameBuffer::FrameBuffer(int max_size, + decoded_frame_history_(max_decode_history) {} + + bool FrameBuffer::InsertFrame(std::unique_ptr frame) { ++ const uint32_t ssrc = ++ frame->PacketInfos().empty() ? 0 : frame->PacketInfos()[0].ssrc(); + if (!ValidReferences(*frame)) { ++ TRACE_EVENT2("webrtc", ++ "FrameBuffer::InsertFrame Frame dropped (Invalid references)", ++ "remote_ssrc", ssrc, "frame_id", frame->Id()); + RTC_DLOG(LS_WARNING) << "Frame " << frame->Id() + << " has invalid references, dropping frame."; + return false; +@@ -78,23 +84,35 @@ bool FrameBuffer::InsertFrame(std::unique_ptr frame) { + if (legacy_frame_id_jump_behavior_ && frame->is_keyframe() && + AheadOf(frame->Timestamp(), + *decoded_frame_history_.GetLastDecodedFrameTimestamp())) { ++ TRACE_EVENT2("webrtc", ++ "FrameBuffer::InsertFrame Frames dropped (OOO + PicId jump)", ++ "remote_ssrc", ssrc, "frame_id", frame->Id()); + RTC_DLOG(LS_WARNING) + << "Keyframe " << frame->Id() + << " has newer timestamp but older picture id, clearing buffer."; + Clear(); + } else { + // Already decoded past this frame. ++ TRACE_EVENT2("webrtc", ++ "FrameBuffer::InsertFrame Frame dropped (Out of order)", ++ "remote_ssrc", ssrc, "frame_id", frame->Id()); + return false; + } + } + + if (frames_.size() == max_size_) { + if (frame->is_keyframe()) { ++ TRACE_EVENT2("webrtc", ++ "FrameBuffer::InsertFrame Frames dropped (KF + Full buffer)", ++ "remote_ssrc", ssrc, "frame_id", frame->Id()); + RTC_DLOG(LS_WARNING) << "Keyframe " << frame->Id() + << " inserted into full buffer, clearing buffer."; + Clear(); + } else { + // No space for this frame. ++ TRACE_EVENT2("webrtc", ++ "FrameBuffer::InsertFrame Frame dropped (Full buffer)", ++ "remote_ssrc", ssrc, "frame_id", frame->Id()); + return false; + } + } +@@ -149,16 +167,31 @@ void FrameBuffer::DropNextDecodableTemporalUnit() { + + void FrameBuffer::UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, + FrameIterator end_it) { ++ uint32_t dropped_ssrc = 0; ++ int64_t dropped_frame_id = 0; + unsigned int num_discarded_packets = 0; + unsigned int num_dropped_frames = + std::count_if(begin_it, end_it, [&](const auto& f) { + if (f.second.encoded_frame) { + const auto& packetInfos = f.second.encoded_frame->PacketInfos(); ++ dropped_frame_id = f.first; ++ if (!packetInfos.empty()) { ++ dropped_ssrc = packetInfos[0].ssrc(); ++ } + num_discarded_packets += packetInfos.size(); + } + return f.second.encoded_frame != nullptr; + }); + ++ if (num_dropped_frames > 0) { ++ TRACE_EVENT2("webrtc", "FrameBuffer Dropping Old Frames", "remote_ssrc", ++ dropped_ssrc, "frame_id", dropped_frame_id); ++ } ++ if (num_discarded_packets > 0) { ++ TRACE_EVENT2("webrtc", "FrameBuffer Discarding Old Packets", "remote_ssrc", ++ dropped_ssrc, "frame_id", dropped_frame_id); ++ } ++ + num_dropped_frames_ += num_dropped_frames; + num_discarded_packets_ += num_discarded_packets; + } diff --git a/video/receive_statistics_proxy2.cc b/video/receive_statistics_proxy2.cc -index 020e4bb0ae..f5011c46ef 100644 +index f5011c46ef..508c36eaaf 100644 --- a/video/receive_statistics_proxy2.cc +++ b/video/receive_statistics_proxy2.cc -@@ -960,8 +960,13 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { - } +@@ -20,6 +20,7 @@ + #include "rtc_base/strings/string_builder.h" + #include "rtc_base/thread.h" + #include "rtc_base/time_utils.h" ++#include "rtc_base/trace_event.h" + #include "system_wrappers/include/clock.h" + #include "system_wrappers/include/metrics.h" + #include "video/video_receive_stream2.h" +@@ -921,6 +922,9 @@ void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, + VideoContentType content_type) { + RTC_DCHECK_RUN_ON(&main_thread_); ++ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnCompleteFrame", ++ "remote_ssrc", remote_ssrc_, "is_keyframe", is_keyframe); ++ + if (is_keyframe) { + ++stats_.frame_counts.key_frames; + } else { +@@ -952,6 +956,8 @@ void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, + void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { + // Can be called on either the decode queue or the worker thread + // See FrameBuffer2 for more details. ++ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnDroppedFrames", ++ "remote_ssrc", remote_ssrc_, "frames_dropped", frames_dropped); + worker_thread_->PostTask( + SafeTask(task_safety_.flag(), [frames_dropped, this]() { + RTC_DCHECK_RUN_ON(&main_thread_); +@@ -962,6 +968,9 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { void ReceiveStatisticsProxy::OnDiscardedPackets(uint32_t packets_discarded) { -- RTC_DCHECK_RUN_ON(&main_thread_); -- stats_.packets_discarded += packets_discarded; -+ // Can be called on either the decode queue or the worker thread -+ // See FrameBuffer2 for more details. -+ worker_thread_->PostTask( -+ SafeTask(task_safety_.flag(), [packets_discarded, this]() { -+ RTC_DCHECK_RUN_ON(&main_thread_); -+ stats_.packets_discarded += packets_discarded; -+ })); + // Can be called on either the decode queue or the worker thread + // See FrameBuffer2 for more details. ++ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnDiscardedPackets", ++ "remote_ssrc", remote_ssrc_, "packets_discarded", ++ packets_discarded); + worker_thread_->PostTask( + SafeTask(task_safety_.flag(), [packets_discarded, this]() { + RTC_DCHECK_RUN_ON(&main_thread_); +@@ -991,6 +1000,8 @@ void ReceiveStatisticsProxy::OnStreamInactive() { + + void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms) { + RTC_DCHECK_RUN_ON(&main_thread_); ++ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnRttUpdate", ++ "remote_ssrc", remote_ssrc_, "avg_rtt_ms", avg_rtt_ms); + avg_rtt_ms_ = avg_rtt_ms; } - void ReceiveStatisticsProxy::OnPreDecode(VideoCodecType codec_type, int qp) { diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc -index 993745ba9d..289c8990bb 100644 +index 289c8990bb..61ee86ee35 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc -@@ -1209,7 +1209,9 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { - packet_infos_.erase(packet_infos_.begin(), +@@ -44,6 +44,7 @@ + #include "rtc_base/checks.h" + #include "rtc_base/logging.h" + #include "rtc_base/strings/string_builder.h" ++#include "rtc_base/trace_event.h" + #include "system_wrappers/include/metrics.h" + #include "system_wrappers/include/ntp_time.h" + +@@ -1210,6 +1211,9 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { packet_infos_.upper_bound(unwrapped_rtp_seq_num)); uint32_t num_packets_cleared = packet_buffer_.ClearTo(seq_num); -- vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); -+ if (num_packets_cleared > 0) { -+ vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); -+ } + if (num_packets_cleared > 0) { ++ TRACE_EVENT2("webrtc", ++ "RtpVideoStreamReceiver2::FrameDecoded Cleared Old Packets", ++ "remote_ssrc", config_.rtp.remote_ssrc, "seq_num", seq_num); + vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); + } reference_finder_->ClearTo(seq_num); - } - } +diff --git a/video/video_stream_buffer_controller.cc b/video/video_stream_buffer_controller.cc +index cc2b7854cf..b543103c7b 100644 +--- a/video/video_stream_buffer_controller.cc ++++ b/video/video_stream_buffer_controller.cc +@@ -30,6 +30,7 @@ + #include "rtc_base/checks.h" + #include "rtc_base/logging.h" + #include "rtc_base/thread_annotations.h" ++#include "rtc_base/trace_event.h" + #include "video/frame_decode_scheduler.h" + #include "video/frame_decode_timing.h" + #include "video/task_queue_frame_decode_scheduler.h" +@@ -141,6 +142,9 @@ absl::optional VideoStreamBufferController::InsertFrame( + std::unique_ptr frame) { + RTC_DCHECK_RUN_ON(&worker_sequence_checker_); + FrameMetadata metadata(*frame); ++ const uint32_t ssrc = ++ frame->PacketInfos().empty() ? 0 : frame->PacketInfos()[0].ssrc(); ++ const int64_t frameId = frame->Id(); + int complete_units = buffer_->GetTotalNumberOfContinuousTemporalUnits(); + if (buffer_->InsertFrame(std::move(frame))) { + RTC_DCHECK(metadata.receive_time) << "Frame receive time must be set!"; +@@ -151,6 +155,9 @@ absl::optional VideoStreamBufferController::InsertFrame( + *metadata.receive_time); + } + if (complete_units < buffer_->GetTotalNumberOfContinuousTemporalUnits()) { ++ TRACE_EVENT2("webrtc", ++ "VideoStreamBufferController::InsertFrame Frame Complete", ++ "remote_ssrc", ssrc, "frame_id", frameId); + stats_proxy_->OnCompleteFrame(metadata.is_keyframe, metadata.size, + metadata.contentType); + MaybeScheduleFrameForRelease(); -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0077.patch b/third_party/libwebrtc/moz-patch-stack/0077.patch index d38c60059246f..2ca553232e41f 100644 --- a/third_party/libwebrtc/moz-patch-stack/0077.patch +++ b/third_party/libwebrtc/moz-patch-stack/0077.patch @@ -1,224 +1,30 @@ From: Andreas Pehrson Date: Thu, 6 Jan 2022 00:16:00 +0000 -Subject: Bug 1748458 - Add TRACE_EVENTs for dropped frames and packets for - received video. r=bwc +Subject: Bug 1748458 - Add TRACE_EVENT for keyframe requests. r=bwc -This lets us see in the profiler how many received frames and packets we decide -to drop and the reasons why. - -Differential Revision: https://phabricator.services.mozilla.com/D135062 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/08e252da94c4752eccfd845eef13d8517953cc6a - -Also includes: - -Bug 1804288 - (fix-de7ae5755b) reimplement Bug 1748458 - Add TRACE_EVENTs for dropped frames and packets for received video. r=pehrsons - -Differential Revision: https://phabricator.services.mozilla.com/D163960 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8e9a326a99cd5eaa6e447ff57c01ad9d79a09744 +Differential Revision: https://phabricator.services.mozilla.com/D135113 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5b2a7894ef1cf096d0e8977754507c0820e757fc --- - api/video/frame_buffer.cc | 33 +++++++++++++++++++++++++ - video/receive_statistics_proxy2.cc | 11 +++++++++ - video/rtp_video_stream_receiver2.cc | 4 +++ - video/video_stream_buffer_controller.cc | 7 ++++++ - 4 files changed, 55 insertions(+) + video/rtp_video_stream_receiver2.cc | 6 ++++++ + 1 file changed, 6 insertions(+) -diff --git a/api/video/frame_buffer.cc b/api/video/frame_buffer.cc -index 8267b8e6cb..f5d93f5f76 100644 ---- a/api/video/frame_buffer.cc -+++ b/api/video/frame_buffer.cc -@@ -16,6 +16,7 @@ - #include "absl/container/inlined_vector.h" - #include "rtc_base/logging.h" - #include "rtc_base/numerics/sequence_number_util.h" -+#include "rtc_base/trace_event.h" - - namespace webrtc { - namespace { -@@ -68,7 +69,12 @@ FrameBuffer::FrameBuffer(int max_size, - decoded_frame_history_(max_decode_history) {} - - bool FrameBuffer::InsertFrame(std::unique_ptr frame) { -+ const uint32_t ssrc = -+ frame->PacketInfos().empty() ? 0 : frame->PacketInfos()[0].ssrc(); - if (!ValidReferences(*frame)) { -+ TRACE_EVENT2("webrtc", -+ "FrameBuffer::InsertFrame Frame dropped (Invalid references)", -+ "remote_ssrc", ssrc, "frame_id", frame->Id()); - RTC_DLOG(LS_WARNING) << "Frame " << frame->Id() - << " has invalid references, dropping frame."; - return false; -@@ -78,23 +84,35 @@ bool FrameBuffer::InsertFrame(std::unique_ptr frame) { - if (legacy_frame_id_jump_behavior_ && frame->is_keyframe() && - AheadOf(frame->Timestamp(), - *decoded_frame_history_.GetLastDecodedFrameTimestamp())) { -+ TRACE_EVENT2("webrtc", -+ "FrameBuffer::InsertFrame Frames dropped (OOO + PicId jump)", -+ "remote_ssrc", ssrc, "frame_id", frame->Id()); - RTC_DLOG(LS_WARNING) - << "Keyframe " << frame->Id() - << " has newer timestamp but older picture id, clearing buffer."; - Clear(); - } else { - // Already decoded past this frame. -+ TRACE_EVENT2("webrtc", -+ "FrameBuffer::InsertFrame Frame dropped (Out of order)", -+ "remote_ssrc", ssrc, "frame_id", frame->Id()); - return false; - } - } - - if (frames_.size() == max_size_) { - if (frame->is_keyframe()) { -+ TRACE_EVENT2("webrtc", -+ "FrameBuffer::InsertFrame Frames dropped (KF + Full buffer)", -+ "remote_ssrc", ssrc, "frame_id", frame->Id()); - RTC_DLOG(LS_WARNING) << "Keyframe " << frame->Id() - << " inserted into full buffer, clearing buffer."; - Clear(); - } else { - // No space for this frame. -+ TRACE_EVENT2("webrtc", -+ "FrameBuffer::InsertFrame Frame dropped (Full buffer)", -+ "remote_ssrc", ssrc, "frame_id", frame->Id()); - return false; - } - } -@@ -149,16 +167,31 @@ void FrameBuffer::DropNextDecodableTemporalUnit() { - - void FrameBuffer::UpdateDroppedFramesAndDiscardedPackets(FrameIterator begin_it, - FrameIterator end_it) { -+ uint32_t dropped_ssrc = 0; -+ int64_t dropped_frame_id = 0; - unsigned int num_discarded_packets = 0; - unsigned int num_dropped_frames = - std::count_if(begin_it, end_it, [&](const auto& f) { - if (f.second.encoded_frame) { - const auto& packetInfos = f.second.encoded_frame->PacketInfos(); -+ dropped_frame_id = f.first; -+ if (!packetInfos.empty()) { -+ dropped_ssrc = packetInfos[0].ssrc(); -+ } - num_discarded_packets += packetInfos.size(); - } - return f.second.encoded_frame != nullptr; - }); - -+ if (num_dropped_frames > 0) { -+ TRACE_EVENT2("webrtc", "FrameBuffer Dropping Old Frames", "remote_ssrc", -+ dropped_ssrc, "frame_id", dropped_frame_id); -+ } -+ if (num_discarded_packets > 0) { -+ TRACE_EVENT2("webrtc", "FrameBuffer Discarding Old Packets", "remote_ssrc", -+ dropped_ssrc, "frame_id", dropped_frame_id); -+ } -+ - num_dropped_frames_ += num_dropped_frames; - num_discarded_packets_ += num_discarded_packets; - } -diff --git a/video/receive_statistics_proxy2.cc b/video/receive_statistics_proxy2.cc -index f5011c46ef..508c36eaaf 100644 ---- a/video/receive_statistics_proxy2.cc -+++ b/video/receive_statistics_proxy2.cc -@@ -20,6 +20,7 @@ - #include "rtc_base/strings/string_builder.h" - #include "rtc_base/thread.h" - #include "rtc_base/time_utils.h" -+#include "rtc_base/trace_event.h" - #include "system_wrappers/include/clock.h" - #include "system_wrappers/include/metrics.h" - #include "video/video_receive_stream2.h" -@@ -921,6 +922,9 @@ void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, - VideoContentType content_type) { - RTC_DCHECK_RUN_ON(&main_thread_); - -+ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnCompleteFrame", -+ "remote_ssrc", remote_ssrc_, "is_keyframe", is_keyframe); -+ - if (is_keyframe) { - ++stats_.frame_counts.key_frames; - } else { -@@ -952,6 +956,8 @@ void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, - void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { - // Can be called on either the decode queue or the worker thread - // See FrameBuffer2 for more details. -+ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnDroppedFrames", -+ "remote_ssrc", remote_ssrc_, "frames_dropped", frames_dropped); - worker_thread_->PostTask( - SafeTask(task_safety_.flag(), [frames_dropped, this]() { - RTC_DCHECK_RUN_ON(&main_thread_); -@@ -962,6 +968,9 @@ void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) { - void ReceiveStatisticsProxy::OnDiscardedPackets(uint32_t packets_discarded) { - // Can be called on either the decode queue or the worker thread - // See FrameBuffer2 for more details. -+ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnDiscardedPackets", -+ "remote_ssrc", remote_ssrc_, "packets_discarded", -+ packets_discarded); - worker_thread_->PostTask( - SafeTask(task_safety_.flag(), [packets_discarded, this]() { - RTC_DCHECK_RUN_ON(&main_thread_); -@@ -991,6 +1000,8 @@ void ReceiveStatisticsProxy::OnStreamInactive() { - - void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms) { - RTC_DCHECK_RUN_ON(&main_thread_); -+ TRACE_EVENT2("webrtc", "ReceiveStatisticsProxy::OnRttUpdate", -+ "remote_ssrc", remote_ssrc_, "avg_rtt_ms", avg_rtt_ms); - avg_rtt_ms_ = avg_rtt_ms; - } - diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc -index 289c8990bb..61ee86ee35 100644 +index 61ee86ee35..ec0242e915 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc -@@ -44,6 +44,7 @@ - #include "rtc_base/checks.h" - #include "rtc_base/logging.h" - #include "rtc_base/strings/string_builder.h" -+#include "rtc_base/trace_event.h" - #include "system_wrappers/include/metrics.h" - #include "system_wrappers/include/ntp_time.h" - -@@ -1210,6 +1211,9 @@ void RtpVideoStreamReceiver2::FrameDecoded(int64_t picture_id) { - packet_infos_.upper_bound(unwrapped_rtp_seq_num)); - uint32_t num_packets_cleared = packet_buffer_.ClearTo(seq_num); - if (num_packets_cleared > 0) { -+ TRACE_EVENT2("webrtc", -+ "RtpVideoStreamReceiver2::FrameDecoded Cleared Old Packets", -+ "remote_ssrc", config_.rtp.remote_ssrc, "seq_num", seq_num); - vcm_receive_statistics_->OnDiscardedPackets(num_packets_cleared); - } - reference_finder_->ClearTo(seq_num); -diff --git a/video/video_stream_buffer_controller.cc b/video/video_stream_buffer_controller.cc -index cc2b7854cf..b543103c7b 100644 ---- a/video/video_stream_buffer_controller.cc -+++ b/video/video_stream_buffer_controller.cc -@@ -30,6 +30,7 @@ - #include "rtc_base/checks.h" - #include "rtc_base/logging.h" - #include "rtc_base/thread_annotations.h" -+#include "rtc_base/trace_event.h" - #include "video/frame_decode_scheduler.h" - #include "video/frame_decode_timing.h" - #include "video/task_queue_frame_decode_scheduler.h" -@@ -141,6 +142,9 @@ absl::optional VideoStreamBufferController::InsertFrame( - std::unique_ptr frame) { - RTC_DCHECK_RUN_ON(&worker_sequence_checker_); - FrameMetadata metadata(*frame); -+ const uint32_t ssrc = -+ frame->PacketInfos().empty() ? 0 : frame->PacketInfos()[0].ssrc(); -+ const int64_t frameId = frame->Id(); - int complete_units = buffer_->GetTotalNumberOfContinuousTemporalUnits(); - if (buffer_->InsertFrame(std::move(frame))) { - RTC_DCHECK(metadata.receive_time) << "Frame receive time must be set!"; -@@ -151,6 +155,9 @@ absl::optional VideoStreamBufferController::InsertFrame( - *metadata.receive_time); - } - if (complete_units < buffer_->GetTotalNumberOfContinuousTemporalUnits()) { -+ TRACE_EVENT2("webrtc", -+ "VideoStreamBufferController::InsertFrame Frame Complete", -+ "remote_ssrc", ssrc, "frame_id", frameId); - stats_proxy_->OnCompleteFrame(metadata.is_keyframe, metadata.size, - metadata.contentType); - MaybeScheduleFrameForRelease(); +@@ -735,6 +735,12 @@ void RtpVideoStreamReceiver2::OnRtpPacket(const RtpPacketReceived& packet) { + + void RtpVideoStreamReceiver2::RequestKeyFrame() { + RTC_DCHECK_RUN_ON(&worker_task_checker_); ++ TRACE_EVENT2("webrtc", "RtpVideoStreamReceiver2::RequestKeyFrame", ++ "remote_ssrc", config_.rtp.remote_ssrc, "method", ++ keyframe_request_method_ == KeyFrameReqMethod::kPliRtcp ? "PLI" ++ : keyframe_request_method_ == KeyFrameReqMethod::kFirRtcp ? "FIR" ++ : keyframe_request_method_ == KeyFrameReqMethod::kNone ? "None" ++ : "Other"); + // TODO(bugs.webrtc.org/10336): Allow the sender to ignore key frame requests + // issued by anything other than the LossNotificationController if it (the + // sender) is relying on LNTF alone. -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0078.patch b/third_party/libwebrtc/moz-patch-stack/0078.patch index 2ca553232e41f..51b6e32205671 100644 --- a/third_party/libwebrtc/moz-patch-stack/0078.patch +++ b/third_party/libwebrtc/moz-patch-stack/0078.patch @@ -1,30 +1,26 @@ From: Andreas Pehrson -Date: Thu, 6 Jan 2022 00:16:00 +0000 -Subject: Bug 1748458 - Add TRACE_EVENT for keyframe requests. r=bwc +Date: Wed, 11 Jan 2023 22:42:00 +0000 +Subject: Bug 1800942 - Add DCHECKs to + TimestampExtrapolator::ExtrapolateLocalTime. r=mjf -Differential Revision: https://phabricator.services.mozilla.com/D135113 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5b2a7894ef1cf096d0e8977754507c0820e757fc +Differential Revision: https://phabricator.services.mozilla.com/D166536 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c5df7f40392464ffc63f44a53ddcaab2091741e0 --- - video/rtp_video_stream_receiver2.cc | 6 ++++++ - 1 file changed, 6 insertions(+) + modules/video_coding/timing/timestamp_extrapolator.cc | 1 + + 1 file changed, 1 insertion(+) -diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc -index 61ee86ee35..ec0242e915 100644 ---- a/video/rtp_video_stream_receiver2.cc -+++ b/video/rtp_video_stream_receiver2.cc -@@ -735,6 +735,12 @@ void RtpVideoStreamReceiver2::OnRtpPacket(const RtpPacketReceived& packet) { +diff --git a/modules/video_coding/timing/timestamp_extrapolator.cc b/modules/video_coding/timing/timestamp_extrapolator.cc +index a90df8bf7f..77e5508a76 100644 +--- a/modules/video_coding/timing/timestamp_extrapolator.cc ++++ b/modules/video_coding/timing/timestamp_extrapolator.cc +@@ -125,6 +125,7 @@ void TimestampExtrapolator::Update(Timestamp now, uint32_t ts90khz) { + absl::optional TimestampExtrapolator::ExtrapolateLocalTime( + uint32_t timestamp90khz) const { + int64_t unwrapped_ts90khz = unwrapper_.PeekUnwrap(timestamp90khz); ++ RTC_DCHECK_GE(unwrapped_ts90khz, 0); - void RtpVideoStreamReceiver2::RequestKeyFrame() { - RTC_DCHECK_RUN_ON(&worker_task_checker_); -+ TRACE_EVENT2("webrtc", "RtpVideoStreamReceiver2::RequestKeyFrame", -+ "remote_ssrc", config_.rtp.remote_ssrc, "method", -+ keyframe_request_method_ == KeyFrameReqMethod::kPliRtcp ? "PLI" -+ : keyframe_request_method_ == KeyFrameReqMethod::kFirRtcp ? "FIR" -+ : keyframe_request_method_ == KeyFrameReqMethod::kNone ? "None" -+ : "Other"); - // TODO(bugs.webrtc.org/10336): Allow the sender to ignore key frame requests - // issued by anything other than the LossNotificationController if it (the - // sender) is relying on LNTF alone. + if (!first_unwrapped_timestamp_) { + return absl::nullopt; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0079.patch b/third_party/libwebrtc/moz-patch-stack/0079.patch index 39abbd9995887..69a6d4978fcf4 100644 --- a/third_party/libwebrtc/moz-patch-stack/0079.patch +++ b/third_party/libwebrtc/moz-patch-stack/0079.patch @@ -1,45 +1,28 @@ From: Andreas Pehrson -Date: Wed, 11 Jan 2023 22:42:00 +0000 -Subject: Bug 1800942 - Add DCHECKs to - TimestampExtrapolator::ExtrapolateLocalTime. r=mjf +Date: Wed, 8 Feb 2023 08:01:00 +0000 +Subject: Bug 1814692 - Don't attempt realtime scheduling rtc::PlatformThreads. + r=webrtc-reviewers,bwc -Differential Revision: https://phabricator.services.mozilla.com/D166536 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c5df7f40392464ffc63f44a53ddcaab2091741e0 +Differential Revision: https://phabricator.services.mozilla.com/D169036 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/9e64a965e26c8379261466e5273c3b383164b2c7 --- - modules/video_coding/timing/timestamp_extrapolator.cc | 7 +++++++ - 1 file changed, 7 insertions(+) + rtc_base/platform_thread.cc | 3 +++ + 1 file changed, 3 insertions(+) -diff --git a/modules/video_coding/timing/timestamp_extrapolator.cc b/modules/video_coding/timing/timestamp_extrapolator.cc -index c91aa1a362..dc62ac674a 100644 ---- a/modules/video_coding/timing/timestamp_extrapolator.cc -+++ b/modules/video_coding/timing/timestamp_extrapolator.cc -@@ -125,6 +125,7 @@ void TimestampExtrapolator::Update(Timestamp now, uint32_t ts90khz) { - absl::optional TimestampExtrapolator::ExtrapolateLocalTime( - uint32_t timestamp90khz) const { - int64_t unwrapped_ts90khz = unwrapper_.PeekUnwrap(timestamp90khz); -+ RTC_DCHECK_GE(unwrapped_ts90khz, 0); - - if (!first_unwrapped_timestamp_) { - return absl::nullopt; -@@ -132,12 +133,18 @@ absl::optional TimestampExtrapolator::ExtrapolateLocalTime( - constexpr double kRtpTicksPerMs = 90; - TimeDelta diff = TimeDelta::Millis( - (unwrapped_ts90khz - *prev_unwrapped_timestamp_) / kRtpTicksPerMs); -+ if (diff.ms() < 0) { -+ RTC_DCHECK_GE(prev_.ms(), -diff.ms()); -+ } - return prev_ + diff; - } else if (w_[0] < 1e-3) { - return start_; - } else { - double timestampDiff = unwrapped_ts90khz - *first_unwrapped_timestamp_; - auto diff_ms = static_cast((timestampDiff - w_[1]) / w_[0] + 0.5); -+ if (diff_ms < 0) { -+ RTC_DCHECK_GE(start_.ms(), -diff_ms); -+ } - return start_ + TimeDelta::Millis(diff_ms); - } - } +diff --git a/rtc_base/platform_thread.cc b/rtc_base/platform_thread.cc +index 71a9f1b224..bcbb784b97 100644 +--- a/rtc_base/platform_thread.cc ++++ b/rtc_base/platform_thread.cc +@@ -50,6 +50,9 @@ bool SetPriority(ThreadPriority priority) { + // TODO(tommi): Switch to the same mechanism as Chromium uses for changing + // thread priorities. + return true; ++#elif defined(WEBRTC_MOZILLA_BUILD) && defined(WEBRTC_LINUX) ++ // Only realtime audio uses realtime scheduling in Firefox. ++ return true; + #else + const int policy = SCHED_FIFO; + const int min_prio = sched_get_priority_min(policy); -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0080.patch b/third_party/libwebrtc/moz-patch-stack/0080.patch index 69a6d4978fcf4..d3db0fa12fc25 100644 --- a/third_party/libwebrtc/moz-patch-stack/0080.patch +++ b/third_party/libwebrtc/moz-patch-stack/0080.patch @@ -1,28 +1,34 @@ From: Andreas Pehrson -Date: Wed, 8 Feb 2023 08:01:00 +0000 -Subject: Bug 1814692 - Don't attempt realtime scheduling rtc::PlatformThreads. - r=webrtc-reviewers,bwc +Date: Fri, 24 Feb 2023 15:01:00 +0100 +Subject: Bug 1817024 - (fix-0e2cf6cc01) Skip library + create_peer_connection_quality_test_frame_generator. r?mjf! -Differential Revision: https://phabricator.services.mozilla.com/D169036 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/9e64a965e26c8379261466e5273c3b383164b2c7 +Differential Revision: https://phabricator.services.mozilla.com/D170887 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fbbc1bf963fda30bca26ae6aac0c3459b8ebea6f --- - rtc_base/platform_thread.cc | 3 +++ - 1 file changed, 3 insertions(+) + api/BUILD.gn | 2 ++ + 1 file changed, 2 insertions(+) -diff --git a/rtc_base/platform_thread.cc b/rtc_base/platform_thread.cc -index 71a9f1b224..bcbb784b97 100644 ---- a/rtc_base/platform_thread.cc -+++ b/rtc_base/platform_thread.cc -@@ -50,6 +50,9 @@ bool SetPriority(ThreadPriority priority) { - // TODO(tommi): Switch to the same mechanism as Chromium uses for changing - // thread priorities. - return true; -+#elif defined(WEBRTC_MOZILLA_BUILD) && defined(WEBRTC_LINUX) -+ // Only realtime audio uses realtime scheduling in Firefox. -+ return true; - #else - const int policy = SCHED_FIFO; - const int min_prio = sched_get_priority_min(policy); +diff --git a/api/BUILD.gn b/api/BUILD.gn +index 4ca73b99f5..3ef383e1bc 100644 +--- a/api/BUILD.gn ++++ b/api/BUILD.gn +@@ -738,6 +738,7 @@ rtc_library("create_frame_generator") { + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + } + ++if (!build_with_mozilla) { + rtc_library("create_peer_connection_quality_test_frame_generator") { + visibility = [ "*" ] + testonly = true +@@ -754,6 +755,7 @@ rtc_library("create_peer_connection_quality_test_frame_generator") { + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + } ++} + + rtc_source_set("libjingle_logging_api") { + visibility = [ "*" ] -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0081.patch b/third_party/libwebrtc/moz-patch-stack/0081.patch index 18a806f08953e..e87eaff066526 100644 --- a/third_party/libwebrtc/moz-patch-stack/0081.patch +++ b/third_party/libwebrtc/moz-patch-stack/0081.patch @@ -1,34 +1,33 @@ -From: Andreas Pehrson -Date: Fri, 24 Feb 2023 15:01:00 +0100 -Subject: Bug 1817024 - (fix-0e2cf6cc01) Skip library - create_peer_connection_quality_test_frame_generator. r?mjf! +From: Michael Froman +Date: Wed, 12 Apr 2023 16:03:00 +0000 +Subject: Bug 1826428 - remove libwebrtc's jvm_android.cc from build + r=ng,webrtc-reviewers -Differential Revision: https://phabricator.services.mozilla.com/D170887 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fbbc1bf963fda30bca26ae6aac0c3459b8ebea6f +Based on info from John Lin and previous try runs, we're almost +certainly not using this. Let's try removing it from the build +and landing it. If no problems emerge, we'll be able to remove +our custom changes to upstream code in jvm_android.cc. + +Differential Revision: https://phabricator.services.mozilla.com/D174793 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/dca1b97525487ae57d43ced1ebdb4a2d9c9dae89 --- - api/BUILD.gn | 2 ++ - 1 file changed, 2 insertions(+) + modules/utility/BUILD.gn | 4 ++++ + 1 file changed, 4 insertions(+) -diff --git a/api/BUILD.gn b/api/BUILD.gn -index abc92cf4a8..86552cdab5 100644 ---- a/api/BUILD.gn -+++ b/api/BUILD.gn -@@ -737,6 +737,7 @@ rtc_library("create_frame_generator") { - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] - } - -+if (!build_with_mozilla) { - rtc_library("create_peer_connection_quality_test_frame_generator") { - visibility = [ "*" ] - testonly = true -@@ -753,6 +754,7 @@ rtc_library("create_peer_connection_quality_test_frame_generator") { - ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +diff --git a/modules/utility/BUILD.gn b/modules/utility/BUILD.gn +index 8cefe5653c..b8d75865f7 100644 +--- a/modules/utility/BUILD.gn ++++ b/modules/utility/BUILD.gn +@@ -25,5 +25,9 @@ rtc_source_set("utility") { + "../../rtc_base:platform_thread", + "../../rtc_base/system:arch", + ] ++ ++ if (build_with_mozilla) { ++ sources -= [ "source/jvm_android.cc" ] ++ } + } } -+} - - rtc_source_set("libjingle_logging_api") { - visibility = [ "*" ] -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0082.patch b/third_party/libwebrtc/moz-patch-stack/0082.patch index 1e5dcbce096fb..df049975b4709 100644 --- a/third_party/libwebrtc/moz-patch-stack/0082.patch +++ b/third_party/libwebrtc/moz-patch-stack/0082.patch @@ -1,31 +1,166 @@ -From: Michael Froman -Date: Wed, 12 Apr 2023 16:03:00 +0000 -Subject: Bug 1826428 - remove libwebrtc's jvm_android.cc from build - r=ng,webrtc-reviewers +From: Jan Grulich +Date: Mon, 20 Feb 2023 21:25:00 +0000 +Subject: Bug 1817263 - fix OS picker behavior under Wayland r=ng,jib,stransky -Based on info from John Lin and previous try runs, we're almost -certainly not using this. Let's try removing it from the build -and landing it. If no problems emerge, we'll be able to remove -our custom changes to upstream code in jvm_android.cc. +Recent WebRTC backports and changes that are about to be backported from +upstream to Firefox breaks and will break how we work with PipWire based +desktop capturer. Currently when constructing device list, a fallback to +ScreenCapturerX11 is used, as we don't call set_allow_pipewire(), which +wouldn't make a difference anyway. In such case the only thing we need +is a placeholder for a screen that will request OS level prompt. We also +need a way to request both screens and windows in one xdg-desktop-portal +call as recent WebRTC made each type be called separately, therefore the +introduction of GenericCapturer. Lastly we need to make sure when there +is a MediaDevice requesting the OS prompt, that it will be checked as +first. -Differential Revision: https://phabricator.services.mozilla.com/D174793 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/dca1b97525487ae57d43ced1ebdb4a2d9c9dae89 +In order to use unmodified libwebrtc, Firefox would need to rework the +OS picker to request each type (screens and windows) separately so we +can just use regular ScreenCapturer and WindowCapturer. This should be +done ideally the way Chromium does it, where users can actually see +even the preview of what they picked over xdg-desktop-portal before it +is actually shared with requesting web page and they also have option +to make the request again in case they picked a wrong window or screen. + +Differential Revision: https://phabricator.services.mozilla.com/D169627 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/acd6266642951aacf8915a56777c780cae9e9af3 --- - modules/utility/BUILD.gn | 4 ++++ - 1 file changed, 4 insertions(+) + .../desktop_capture/desktop_capture_types.h | 2 +- + modules/desktop_capture/desktop_capturer.cc | 28 +++++++++++++++++++ + modules/desktop_capture/desktop_capturer.h | 13 +++++++++ + .../linux/wayland/base_capturer_pipewire.cc | 11 +------- + .../linux/wayland/screencast_portal.cc | 2 ++ + 5 files changed, 45 insertions(+), 11 deletions(-) -diff --git a/modules/utility/BUILD.gn b/modules/utility/BUILD.gn -index 3fe4ca8c92..46bca17f02 100644 ---- a/modules/utility/BUILD.gn -+++ b/modules/utility/BUILD.gn -@@ -47,6 +47,10 @@ rtc_source_set("utility") { - "../../rtc_base:platform_thread", - "../../rtc_base/system:arch", - ] +diff --git a/modules/desktop_capture/desktop_capture_types.h b/modules/desktop_capture/desktop_capture_types.h +index 381d1021c4..e777a45f92 100644 +--- a/modules/desktop_capture/desktop_capture_types.h ++++ b/modules/desktop_capture/desktop_capture_types.h +@@ -19,7 +19,7 @@ typedef int pid_t; // matching what used to be in + + namespace webrtc { + +-enum class CaptureType { kWindow, kScreen }; ++enum class CaptureType { kWindow, kScreen, kAnyScreenContent }; + + // Type used to identify windows on the desktop. Values are platform-specific: + // - On Windows: HWND cast to intptr_t. +diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc +index 4baa93cab9..7df6becb4e 100644 +--- a/modules/desktop_capture/desktop_capturer.cc ++++ b/modules/desktop_capture/desktop_capturer.cc +@@ -26,6 +26,10 @@ + #include "rtc_base/win/windows_version.h" + #endif // defined(RTC_ENABLE_WIN_WGC) + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++#include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" ++#endif ++ + namespace webrtc { + + void LogDesktopCapturerFullscreenDetectorUsage() { +@@ -84,6 +88,30 @@ std::unique_ptr DesktopCapturer::CreateWindowCapturer( + return capturer; + } + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++// static ++std::unique_ptr DesktopCapturer::CreateGenericCapturer( ++ const DesktopCaptureOptions& options) { ++ std::unique_ptr capturer = CreateRawGenericCapturer(options); ++ if (capturer && options.detect_updated_region()) { ++ capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); ++ } ++ ++ return capturer; ++} + -+ if (build_with_mozilla) { -+ sources -= [ "source/jvm_android.cc" ] -+ } ++// static ++std::unique_ptr DesktopCapturer::CreateRawGenericCapturer( ++ const DesktopCaptureOptions& options) { ++ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { ++ return std::make_unique(options, ++ CaptureType::kAnyScreenContent); ++ } ++ ++ return nullptr; ++} ++#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++ + // static + std::unique_ptr DesktopCapturer::CreateScreenCapturer( + const DesktopCaptureOptions& options) { +diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h +index 9b667739a8..f4e2861025 100644 +--- a/modules/desktop_capture/desktop_capturer.h ++++ b/modules/desktop_capture/desktop_capturer.h +@@ -179,6 +179,12 @@ class RTC_EXPORT DesktopCapturer { + // The return value if `pos` is out of the scope of the source is undefined. + virtual bool IsOccluded(const DesktopVector& pos); + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++ // Creates a DesktopCapturer instance which targets to capture windows and screens. ++ static std::unique_ptr CreateGenericCapturer( ++ const DesktopCaptureOptions& options); ++#endif ++ + // Creates a DesktopCapturer instance which targets to capture windows. + static std::unique_ptr CreateWindowCapturer( + const DesktopCaptureOptions& options); +@@ -207,6 +213,13 @@ class RTC_EXPORT DesktopCapturer { + // CroppingWindowCapturer needs to create raw capturers without wrappers, so + // the following two functions are protected. + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++ // Creates a platform specific DesktopCapturer instance which targets to ++ // capture windows and screens. ++ static std::unique_ptr CreateRawGenericCapturer( ++ const DesktopCaptureOptions& options); ++#endif ++ + // Creates a platform specific DesktopCapturer instance which targets to + // capture windows. + static std::unique_ptr CreateRawWindowCapturer( +diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +index 1ae0a4c794..4ef00e68ab 100644 +--- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc ++++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +@@ -173,15 +173,6 @@ void BaseCapturerPipeWire::CaptureFrame() { + callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); + } + +-// Keep in sync with defines at browser/actors/WebRTCParent.jsm +-// With PipeWire we can't select which system resource is shared so +-// we don't create a window/screen list. Instead we place these constants +-// as window name/id so frontend code can identify PipeWire backend +-// and does not try to create screen/window preview. +- +-#define PIPEWIRE_ID 0xaffffff +-#define PIPEWIRE_NAME "####_PIPEWIRE_PORTAL_####" +- + bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { + RTC_DCHECK(sources->size() == 0); + // List of available screens is already presented by the xdg-desktop-portal, +@@ -198,7 +189,7 @@ bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { + bool BaseCapturerPipeWire::SelectSource(SourceId id) { + // Screen selection is handled by the xdg-desktop-portal. + selected_source_id_ = id; +- return id == PIPEWIRE_ID; ++ return true; + } + + DelegatedSourceListController* +diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc +index 3d28d42ba6..ebe6779e31 100644 +--- a/modules/desktop_capture/linux/wayland/screencast_portal.cc ++++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc +@@ -41,6 +41,8 @@ ScreenCastPortal::CaptureSourceType ScreenCastPortal::ToCaptureSourceType( + return ScreenCastPortal::CaptureSourceType::kScreen; + case CaptureType::kWindow: + return ScreenCastPortal::CaptureSourceType::kWindow; ++ case CaptureType::kAnyScreenContent: ++ return ScreenCastPortal::CaptureSourceType::kAnyScreenContent; } } diff --git a/third_party/libwebrtc/moz-patch-stack/0083.patch b/third_party/libwebrtc/moz-patch-stack/0083.patch index af42478cb9e5e..12f8098040cc2 100644 --- a/third_party/libwebrtc/moz-patch-stack/0083.patch +++ b/third_party/libwebrtc/moz-patch-stack/0083.patch @@ -1,169 +1,100 @@ From: Jan Grulich -Date: Mon, 20 Feb 2023 21:25:00 +0000 -Subject: Bug 1817263 - fix OS picker behavior under Wayland r=ng,jib,stransky +Date: Mon, 27 Feb 2023 13:57:00 +0000 +Subject: Bug 1819044 - fix build non-pipewire builds + r=webrtc-reviewers,pehrsons -Recent WebRTC backports and changes that are about to be backported from -upstream to Firefox breaks and will break how we work with PipWire based -desktop capturer. Currently when constructing device list, a fallback to -ScreenCapturerX11 is used, as we don't call set_allow_pipewire(), which -wouldn't make a difference anyway. In such case the only thing we need -is a placeholder for a screen that will request OS level prompt. We also -need a way to request both screens and windows in one xdg-desktop-portal -call as recent WebRTC made each type be called separately, therefore the -introduction of GenericCapturer. Lastly we need to make sure when there -is a MediaDevice requesting the OS prompt, that it will be checked as -first. +We should check only for PipeWire presence when building code specific +to PipeWire. -In order to use unmodified libwebrtc, Firefox would need to rework the -OS picker to request each type (screens and windows) separately so we -can just use regular ScreenCapturer and WindowCapturer. This should be -done ideally the way Chromium does it, where users can actually see -even the preview of what they picked over xdg-desktop-portal before it -is actually shared with requesting web page and they also have option -to make the request again in case they picked a wrong window or screen. +Differential Revision: https://phabricator.services.mozilla.com/D171071 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/7a879ad084a6e9768479c73cc5c3f4e9d95a2ab9 -Differential Revision: https://phabricator.services.mozilla.com/D169627 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/acd6266642951aacf8915a56777c780cae9e9af3 +Also includes: + + Bug 1819044 - fix build non-pipewire builds (attempt #2) r=webrtc-reviewers,pehrsons + + Make the new API available to everyone and just return an empty capturer + in case when building without PipeWire. It will not make any difference + because using X11 based capturers on Wayland is useless anyway so if we + fail for missing PipeWire on Wayland, it will have the same outcome. + + Differential Revision: https://phabricator.services.mozilla.com/D171192 + Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/ad247b0aac896d884eba5e40f0ec8a9f50d8b85b --- - .../desktop_capture/desktop_capture_types.h | 2 +- - modules/desktop_capture/desktop_capturer.cc | 28 +++++++++++++++++++ - modules/desktop_capture/desktop_capturer.h | 13 +++++++++ - .../linux/wayland/base_capturer_pipewire.cc | 11 +------- - .../linux/wayland/screencast_portal.cc | 2 ++ - 5 files changed, 45 insertions(+), 11 deletions(-) + modules/desktop_capture/desktop_capturer.cc | 7 +++---- + modules/desktop_capture/desktop_capturer.h | 4 ---- + 2 files changed, 3 insertions(+), 8 deletions(-) -diff --git a/modules/desktop_capture/desktop_capture_types.h b/modules/desktop_capture/desktop_capture_types.h -index 381d1021c4..e777a45f92 100644 ---- a/modules/desktop_capture/desktop_capture_types.h -+++ b/modules/desktop_capture/desktop_capture_types.h -@@ -19,7 +19,7 @@ typedef int pid_t; // matching what used to be in - - namespace webrtc { - --enum class CaptureType { kWindow, kScreen }; -+enum class CaptureType { kWindow, kScreen, kAnyScreenContent }; - - // Type used to identify windows on the desktop. Values are platform-specific: - // - On Windows: HWND cast to intptr_t. diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc -index 4baa93cab9..7df6becb4e 100644 +index 7df6becb4e..1af19a1fd2 100644 --- a/modules/desktop_capture/desktop_capturer.cc +++ b/modules/desktop_capture/desktop_capturer.cc -@@ -26,6 +26,10 @@ +@@ -26,7 +26,7 @@ #include "rtc_base/win/windows_version.h" #endif // defined(RTC_ENABLE_WIN_WGC) -+#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+#include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" -+#endif -+ - namespace webrtc { +-#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) ++#if defined(WEBRTC_USE_PIPEWIRE) + #include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" + #endif - void LogDesktopCapturerFullscreenDetectorUsage() { -@@ -84,6 +88,30 @@ std::unique_ptr DesktopCapturer::CreateWindowCapturer( +@@ -88,7 +88,6 @@ std::unique_ptr DesktopCapturer::CreateWindowCapturer( return capturer; } -+#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+// static -+std::unique_ptr DesktopCapturer::CreateGenericCapturer( -+ const DesktopCaptureOptions& options) { -+ std::unique_ptr capturer = CreateRawGenericCapturer(options); -+ if (capturer && options.detect_updated_region()) { -+ capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); -+ } -+ -+ return capturer; -+} -+ -+// static -+std::unique_ptr DesktopCapturer::CreateRawGenericCapturer( -+ const DesktopCaptureOptions& options) { -+ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { -+ return std::make_unique(options, -+ CaptureType::kAnyScreenContent); -+ } -+ -+ return nullptr; -+} -+#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+ +-#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) // static - std::unique_ptr DesktopCapturer::CreateScreenCapturer( + std::unique_ptr DesktopCapturer::CreateGenericCapturer( const DesktopCaptureOptions& options) { +@@ -100,17 +99,17 @@ std::unique_ptr DesktopCapturer::CreateGenericCapturer( + return capturer; + } + +-// static + std::unique_ptr DesktopCapturer::CreateRawGenericCapturer( + const DesktopCaptureOptions& options) { ++#if defined(WEBRTC_USE_PIPEWIRE) + if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { + return std::make_unique(options, + CaptureType::kAnyScreenContent); + } ++#endif // defined(WEBRTC_USE_PIPEWIRE) + + return nullptr; + } +-#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + + // static + std::unique_ptr DesktopCapturer::CreateScreenCapturer( diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h -index 9b667739a8..f4e2861025 100644 +index f4e2861025..64f3187f51 100644 --- a/modules/desktop_capture/desktop_capturer.h +++ b/modules/desktop_capture/desktop_capturer.h -@@ -179,6 +179,12 @@ class RTC_EXPORT DesktopCapturer { +@@ -179,11 +179,9 @@ class RTC_EXPORT DesktopCapturer { // The return value if `pos` is out of the scope of the source is undefined. virtual bool IsOccluded(const DesktopVector& pos); -+#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+ // Creates a DesktopCapturer instance which targets to capture windows and screens. -+ static std::unique_ptr CreateGenericCapturer( -+ const DesktopCaptureOptions& options); -+#endif -+ +-#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + // Creates a DesktopCapturer instance which targets to capture windows and screens. + static std::unique_ptr CreateGenericCapturer( + const DesktopCaptureOptions& options); +-#endif + // Creates a DesktopCapturer instance which targets to capture windows. static std::unique_ptr CreateWindowCapturer( - const DesktopCaptureOptions& options); -@@ -207,6 +213,13 @@ class RTC_EXPORT DesktopCapturer { +@@ -213,12 +211,10 @@ class RTC_EXPORT DesktopCapturer { // CroppingWindowCapturer needs to create raw capturers without wrappers, so // the following two functions are protected. -+#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+ // Creates a platform specific DesktopCapturer instance which targets to -+ // capture windows and screens. -+ static std::unique_ptr CreateRawGenericCapturer( -+ const DesktopCaptureOptions& options); -+#endif -+ +-#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) // Creates a platform specific DesktopCapturer instance which targets to - // capture windows. - static std::unique_ptr CreateRawWindowCapturer( -diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc -index 1ae0a4c794..4ef00e68ab 100644 ---- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc -+++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc -@@ -173,15 +173,6 @@ void BaseCapturerPipeWire::CaptureFrame() { - callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); - } - --// Keep in sync with defines at browser/actors/WebRTCParent.jsm --// With PipeWire we can't select which system resource is shared so --// we don't create a window/screen list. Instead we place these constants --// as window name/id so frontend code can identify PipeWire backend --// and does not try to create screen/window preview. -- --#define PIPEWIRE_ID 0xaffffff --#define PIPEWIRE_NAME "####_PIPEWIRE_PORTAL_####" -- - bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { - RTC_DCHECK(sources->size() == 0); - // List of available screens is already presented by the xdg-desktop-portal, -@@ -198,7 +189,7 @@ bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { - bool BaseCapturerPipeWire::SelectSource(SourceId id) { - // Screen selection is handled by the xdg-desktop-portal. - selected_source_id_ = id; -- return id == PIPEWIRE_ID; -+ return true; - } - - DelegatedSourceListController* -diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc -index 52788524c8..8d9e956779 100644 ---- a/modules/desktop_capture/linux/wayland/screencast_portal.cc -+++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc -@@ -41,6 +41,8 @@ ScreenCastPortal::CaptureSourceType ScreenCastPortal::ToCaptureSourceType( - return ScreenCastPortal::CaptureSourceType::kScreen; - case CaptureType::kWindow: - return ScreenCastPortal::CaptureSourceType::kWindow; -+ case CaptureType::kAnyScreenContent: -+ return ScreenCastPortal::CaptureSourceType::kAnyScreenContent; - } - } + // capture windows and screens. + static std::unique_ptr CreateRawGenericCapturer( + const DesktopCaptureOptions& options); +-#endif + // Creates a platform specific DesktopCapturer instance which targets to + // capture windows. -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0084.patch b/third_party/libwebrtc/moz-patch-stack/0084.patch index 12f8098040cc2..3f4b4db0b2589 100644 --- a/third_party/libwebrtc/moz-patch-stack/0084.patch +++ b/third_party/libwebrtc/moz-patch-stack/0084.patch @@ -1,100 +1,77 @@ From: Jan Grulich -Date: Mon, 27 Feb 2023 13:57:00 +0000 -Subject: Bug 1819044 - fix build non-pipewire builds - r=webrtc-reviewers,pehrsons +Date: Fri, 10 Mar 2023 09:21:00 +0000 +Subject: Bug 1819035 - get EGL display based on the used platform in the + browser r=webrtc-reviewers,ng -We should check only for PipeWire presence when building code specific -to PipeWire. +Because of a possible misconfiguration or a possible driver issue it +might happen that the browser will use a different driver on X11 and +end up using yet another one for wayland/gbm, which might lead to not +working screen sharing in the better case, but also to a crash in the +other driver (Nvidia). This adds a check for platform the browser runs +on, if it's XWayland or Wayland and based on that query EGL display for +that specific platform, rather than going for the Wayland one only. -Differential Revision: https://phabricator.services.mozilla.com/D171071 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/7a879ad084a6e9768479c73cc5c3f4e9d95a2ab9 - -Also includes: - - Bug 1819044 - fix build non-pipewire builds (attempt #2) r=webrtc-reviewers,pehrsons - - Make the new API available to everyone and just return an empty capturer - in case when building without PipeWire. It will not make any difference - because using X11 based capturers on Wayland is useless anyway so if we - fail for missing PipeWire on Wayland, it will have the same outcome. - - Differential Revision: https://phabricator.services.mozilla.com/D171192 - Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/ad247b0aac896d884eba5e40f0ec8a9f50d8b85b +Differential Revision: https://phabricator.services.mozilla.com/D171858 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c8606497de1f461a6352456e0e511c2ae498d526 --- - modules/desktop_capture/desktop_capturer.cc | 7 +++---- - modules/desktop_capture/desktop_capturer.h | 4 ---- - 2 files changed, 3 insertions(+), 8 deletions(-) + .../linux/wayland/egl_dmabuf.cc | 30 +++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) -diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc -index 7df6becb4e..1af19a1fd2 100644 ---- a/modules/desktop_capture/desktop_capturer.cc -+++ b/modules/desktop_capture/desktop_capturer.cc -@@ -26,7 +26,7 @@ - #include "rtc_base/win/windows_version.h" - #endif // defined(RTC_ENABLE_WIN_WGC) - --#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) -+#if defined(WEBRTC_USE_PIPEWIRE) - #include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" - #endif - -@@ -88,7 +88,6 @@ std::unique_ptr DesktopCapturer::CreateWindowCapturer( - return capturer; - } - --#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - // static - std::unique_ptr DesktopCapturer::CreateGenericCapturer( - const DesktopCaptureOptions& options) { -@@ -100,17 +99,17 @@ std::unique_ptr DesktopCapturer::CreateGenericCapturer( - return capturer; - } - --// static - std::unique_ptr DesktopCapturer::CreateRawGenericCapturer( - const DesktopCaptureOptions& options) { -+#if defined(WEBRTC_USE_PIPEWIRE) - if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { - return std::make_unique(options, - CaptureType::kAnyScreenContent); +diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc +index b529077c6d..6a019c64b4 100644 +--- a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc ++++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -217,6 +218,26 @@ static void CloseLibrary(void* library) { } -+#endif // defined(WEBRTC_USE_PIPEWIRE) - - return nullptr; } --#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - - // static - std::unique_ptr DesktopCapturer::CreateScreenCapturer( -diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h -index f4e2861025..64f3187f51 100644 ---- a/modules/desktop_capture/desktop_capturer.h -+++ b/modules/desktop_capture/desktop_capturer.h -@@ -179,11 +179,9 @@ class RTC_EXPORT DesktopCapturer { - // The return value if `pos` is out of the scope of the source is undefined. - virtual bool IsOccluded(const DesktopVector& pos); --#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - // Creates a DesktopCapturer instance which targets to capture windows and screens. - static std::unique_ptr CreateGenericCapturer( - const DesktopCaptureOptions& options); --#endif ++static bool IsWaylandDisplay() { ++ static auto sGdkWaylandDisplayGetType = ++ (GType (*)(void))dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_type"); ++ if (!sGdkWaylandDisplayGetType) { ++ return false; ++ } ++ return (G_TYPE_CHECK_INSTANCE_TYPE ((gdk_display_get_default()), ++ sGdkWaylandDisplayGetType())); ++} ++ ++static bool IsX11Display() { ++ static auto sGdkX11DisplayGetType = ++ (GType (*)(void))dlsym(RTLD_DEFAULT, "gdk_x11_display_get_type"); ++ if (!sGdkX11DisplayGetType) { ++ return false; ++ } ++ return (G_TYPE_CHECK_INSTANCE_TYPE ((gdk_display_get_default()), ++ sGdkX11DisplayGetType())); ++} ++ + static void* g_lib_egl = nullptr; - // Creates a DesktopCapturer instance which targets to capture windows. - static std::unique_ptr CreateWindowCapturer( -@@ -213,12 +211,10 @@ class RTC_EXPORT DesktopCapturer { - // CroppingWindowCapturer needs to create raw capturers without wrappers, so - // the following two functions are protected. + RTC_NO_SANITIZE("cfi-icall") +@@ -362,8 +383,13 @@ EglDmaBuf::EglDmaBuf() { + return; + } --#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - // Creates a platform specific DesktopCapturer instance which targets to - // capture windows and screens. - static std::unique_ptr CreateRawGenericCapturer( - const DesktopCaptureOptions& options); --#endif +- egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, +- (void*)EGL_DEFAULT_DISPLAY, nullptr); ++ if (IsWaylandDisplay()) { ++ egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, ++ (void*)EGL_DEFAULT_DISPLAY, nullptr); ++ } else if (IsX11Display()) { ++ egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, ++ (void*)EGL_DEFAULT_DISPLAY, nullptr); ++ } - // Creates a platform specific DesktopCapturer instance which targets to - // capture windows. + if (egl_.display == EGL_NO_DISPLAY) { + RTC_LOG(LS_ERROR) << "Failed to obtain default EGL display: " -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0085.patch b/third_party/libwebrtc/moz-patch-stack/0085.patch index 3f4b4db0b2589..c00ba9d6a8769 100644 --- a/third_party/libwebrtc/moz-patch-stack/0085.patch +++ b/third_party/libwebrtc/moz-patch-stack/0085.patch @@ -1,77 +1,34 @@ -From: Jan Grulich -Date: Fri, 10 Mar 2023 09:21:00 +0000 -Subject: Bug 1819035 - get EGL display based on the used platform in the - browser r=webrtc-reviewers,ng +From: Andreas Pehrson +Date: Mon, 27 Feb 2023 16:22:00 +0000 +Subject: Bug 1817024 - (fix-fdcfefa708) In PhysicalSocket avoid a non-trivial + designated initializer. r=mjf,webrtc-reviewers -Because of a possible misconfiguration or a possible driver issue it -might happen that the browser will use a different driver on X11 and -end up using yet another one for wayland/gbm, which might lead to not -working screen sharing in the better case, but also to a crash in the -other driver (Nvidia). This adds a check for platform the browser runs -on, if it's XWayland or Wayland and based on that query EGL display for -that specific platform, rather than going for the Wayland one only. +This fixes a build failure in the base-toolchain job with GCC 7.5.0: + In file included from Unified_cpp_threading_gn0.cpp:38:0: + .../third_party/libwebrtc/rtc_base/physical_socket_server.cc: In member function 'int rtc::PhysicalSocket::DoReadFromSocket(void*, size_t, rtc::SocketAddress*, int64_t*)': + .../third_party/libwebrtc/rtc_base/physical_socket_server.cc:463:51: sorry, unimplemented: non-trivial designated initializers not supported + msghdr msg = {.msg_iov = &iov, .msg_iovlen = 1}; + ^ -Differential Revision: https://phabricator.services.mozilla.com/D171858 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c8606497de1f461a6352456e0e511c2ae498d526 +Differential Revision: https://phabricator.services.mozilla.com/D171057 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a3447f709befd84a282ca40f29b7a5ea76d5b68d --- - .../linux/wayland/egl_dmabuf.cc | 30 +++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) + rtc_base/physical_socket_server.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc -index b529077c6d..6a019c64b4 100644 ---- a/modules/desktop_capture/linux/wayland/egl_dmabuf.cc -+++ b/modules/desktop_capture/linux/wayland/egl_dmabuf.cc -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -217,6 +218,26 @@ static void CloseLibrary(void* library) { - } - } - -+static bool IsWaylandDisplay() { -+ static auto sGdkWaylandDisplayGetType = -+ (GType (*)(void))dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_type"); -+ if (!sGdkWaylandDisplayGetType) { -+ return false; -+ } -+ return (G_TYPE_CHECK_INSTANCE_TYPE ((gdk_display_get_default()), -+ sGdkWaylandDisplayGetType())); -+} -+ -+static bool IsX11Display() { -+ static auto sGdkX11DisplayGetType = -+ (GType (*)(void))dlsym(RTLD_DEFAULT, "gdk_x11_display_get_type"); -+ if (!sGdkX11DisplayGetType) { -+ return false; -+ } -+ return (G_TYPE_CHECK_INSTANCE_TYPE ((gdk_display_get_default()), -+ sGdkX11DisplayGetType())); -+} -+ - static void* g_lib_egl = nullptr; - - RTC_NO_SANITIZE("cfi-icall") -@@ -362,8 +383,13 @@ EglDmaBuf::EglDmaBuf() { - return; - } - -- egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, -- (void*)EGL_DEFAULT_DISPLAY, nullptr); -+ if (IsWaylandDisplay()) { -+ egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, -+ (void*)EGL_DEFAULT_DISPLAY, nullptr); -+ } else if (IsX11Display()) { -+ egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, -+ (void*)EGL_DEFAULT_DISPLAY, nullptr); -+ } - - if (egl_.display == EGL_NO_DISPLAY) { - RTC_LOG(LS_ERROR) << "Failed to obtain default EGL display: " +diff --git a/rtc_base/physical_socket_server.cc b/rtc_base/physical_socket_server.cc +index 2dfdd9a5df..d0053dd82b 100644 +--- a/rtc_base/physical_socket_server.cc ++++ b/rtc_base/physical_socket_server.cc +@@ -462,7 +462,7 @@ int PhysicalSocket::DoReadFromSocket(void* buffer, + int received = 0; + if (read_scm_timestamp_experiment_) { + iovec iov = {.iov_base = buffer, .iov_len = length}; +- msghdr msg = {.msg_iov = &iov, .msg_iovlen = 1}; ++ msghdr msg = {.msg_name = nullptr, .msg_namelen = 0, .msg_iov = &iov, .msg_iovlen = 1}; + if (out_addr) { + out_addr->Clear(); + msg.msg_name = addr; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0086.patch b/third_party/libwebrtc/moz-patch-stack/0086.patch index c00ba9d6a8769..affbb277e232a 100644 --- a/third_party/libwebrtc/moz-patch-stack/0086.patch +++ b/third_party/libwebrtc/moz-patch-stack/0086.patch @@ -1,34 +1,25 @@ -From: Andreas Pehrson -Date: Mon, 27 Feb 2023 16:22:00 +0000 -Subject: Bug 1817024 - (fix-fdcfefa708) In PhysicalSocket avoid a non-trivial - designated initializer. r=mjf,webrtc-reviewers +From: Byron Campen +Date: Tue, 4 Apr 2023 16:34:00 -0500 +Subject: Bug 1822194 - (fix-3b51cd328e) - Add missing designated initializer + that gcc is sad about. -This fixes a build failure in the base-toolchain job with GCC 7.5.0: - In file included from Unified_cpp_threading_gn0.cpp:38:0: - .../third_party/libwebrtc/rtc_base/physical_socket_server.cc: In member function 'int rtc::PhysicalSocket::DoReadFromSocket(void*, size_t, rtc::SocketAddress*, int64_t*)': - .../third_party/libwebrtc/rtc_base/physical_socket_server.cc:463:51: sorry, unimplemented: non-trivial designated initializers not supported - msghdr msg = {.msg_iov = &iov, .msg_iovlen = 1}; - ^ - -Differential Revision: https://phabricator.services.mozilla.com/D171057 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a3447f709befd84a282ca40f29b7a5ea76d5b68d +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/108046c7cbb21c6cf19320c0804e9aee1a3eb4bf --- - rtc_base/physical_socket_server.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + modules/audio_processing/audio_processing_impl.cc | 1 + + 1 file changed, 1 insertion(+) -diff --git a/rtc_base/physical_socket_server.cc b/rtc_base/physical_socket_server.cc -index 2dfdd9a5df..d0053dd82b 100644 ---- a/rtc_base/physical_socket_server.cc -+++ b/rtc_base/physical_socket_server.cc -@@ -462,7 +462,7 @@ int PhysicalSocket::DoReadFromSocket(void* buffer, - int received = 0; - if (read_scm_timestamp_experiment_) { - iovec iov = {.iov_base = buffer, .iov_len = length}; -- msghdr msg = {.msg_iov = &iov, .msg_iovlen = 1}; -+ msghdr msg = {.msg_name = nullptr, .msg_namelen = 0, .msg_iov = &iov, .msg_iovlen = 1}; - if (out_addr) { - out_addr->Clear(); - msg.msg_name = addr; +diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc +index c80cc76a3d..c304453388 100644 +--- a/modules/audio_processing/audio_processing_impl.cc ++++ b/modules/audio_processing/audio_processing_impl.cc +@@ -450,6 +450,7 @@ AudioProcessingImpl::GetGainController2ExperimentParams() { + }, + .adaptive_digital_controller = + { ++ .enabled = false, + .headroom_db = static_cast(headroom_db.Get()), + .max_gain_db = static_cast(max_gain_db.Get()), + .initial_gain_db = -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0087.patch b/third_party/libwebrtc/moz-patch-stack/0087.patch index affbb277e232a..95d608bbaad3e 100644 --- a/third_party/libwebrtc/moz-patch-stack/0087.patch +++ b/third_party/libwebrtc/moz-patch-stack/0087.patch @@ -1,25 +1,27 @@ From: Byron Campen -Date: Tue, 4 Apr 2023 16:34:00 -0500 -Subject: Bug 1822194 - (fix-3b51cd328e) - Add missing designated initializer - that gcc is sad about. +Date: Fri, 7 Apr 2023 20:28:00 +0000 +Subject: Bug 1819048: Remove this bad assertion. r=webrtc-reviewers,jib -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/108046c7cbb21c6cf19320c0804e9aee1a3eb4bf +Differential Revision: https://phabricator.services.mozilla.com/D174978 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5a52e1b0c808edfda82f0abea668699eb68098dc --- - modules/audio_processing/audio_processing_impl.cc | 1 + - 1 file changed, 1 insertion(+) + video/task_queue_frame_decode_scheduler.cc | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) -diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc -index c80cc76a3d..c304453388 100644 ---- a/modules/audio_processing/audio_processing_impl.cc -+++ b/modules/audio_processing/audio_processing_impl.cc -@@ -450,6 +450,7 @@ AudioProcessingImpl::GetGainController2ExperimentParams() { - }, - .adaptive_digital_controller = - { -+ .enabled = false, - .headroom_db = static_cast(headroom_db.Get()), - .max_gain_db = static_cast(max_gain_db.Get()), - .initial_gain_db = +diff --git a/video/task_queue_frame_decode_scheduler.cc b/video/task_queue_frame_decode_scheduler.cc +index cd109c2932..6dd7b47f17 100644 +--- a/video/task_queue_frame_decode_scheduler.cc ++++ b/video/task_queue_frame_decode_scheduler.cc +@@ -37,7 +37,8 @@ void TaskQueueFrameDecodeScheduler::ScheduleFrame( + uint32_t rtp, + FrameDecodeTiming::FrameSchedule schedule, + FrameReleaseCallback cb) { +- RTC_DCHECK(!stopped_) << "Can not schedule frames after stopped."; ++ // Mozilla modification, until https://bugs.webrtc.org/14944 is fixed ++ //RTC_DCHECK(!stopped_) << "Can not schedule frames after stopped."; + RTC_DCHECK(!scheduled_rtp_.has_value()) + << "Can not schedule two frames for release at the same time."; + RTC_DCHECK(cb); -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0088.patch b/third_party/libwebrtc/moz-patch-stack/0088.patch index 95d608bbaad3e..292ae24ca9f8e 100644 --- a/third_party/libwebrtc/moz-patch-stack/0088.patch +++ b/third_party/libwebrtc/moz-patch-stack/0088.patch @@ -1,27 +1,177 @@ -From: Byron Campen -Date: Fri, 7 Apr 2023 20:28:00 +0000 -Subject: Bug 1819048: Remove this bad assertion. r=webrtc-reviewers,jib +From: Michael Froman +Date: Thu, 20 Apr 2023 14:52:00 -0500 +Subject: Bug 1828517 - (fix-a138c6c8a5) handle file moves in BUILD.gn -Differential Revision: https://phabricator.services.mozilla.com/D174978 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/5a52e1b0c808edfda82f0abea668699eb68098dc +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/cf7e333da17689b3c115a6ffd07fab042bc5f086 --- - video/task_queue_frame_decode_scheduler.cc | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + rtc_base/BUILD.gn | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) -diff --git a/video/task_queue_frame_decode_scheduler.cc b/video/task_queue_frame_decode_scheduler.cc -index cd109c2932..6dd7b47f17 100644 ---- a/video/task_queue_frame_decode_scheduler.cc -+++ b/video/task_queue_frame_decode_scheduler.cc -@@ -37,7 +37,8 @@ void TaskQueueFrameDecodeScheduler::ScheduleFrame( - uint32_t rtp, - FrameDecodeTiming::FrameSchedule schedule, - FrameReleaseCallback cb) { -- RTC_DCHECK(!stopped_) << "Can not schedule frames after stopped."; -+ // Mozilla modification, until https://bugs.webrtc.org/14944 is fixed -+ //RTC_DCHECK(!stopped_) << "Can not schedule frames after stopped."; - RTC_DCHECK(!scheduled_rtp_.has_value()) - << "Can not schedule two frames for release at the same time."; - RTC_DCHECK(cb); +diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn +index e474ba8202..8f1be481ef 100644 +--- a/rtc_base/BUILD.gn ++++ b/rtc_base/BUILD.gn +@@ -1154,6 +1154,7 @@ if (!build_with_chromium) { + } + + rtc_library("network") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "network.cc", +@@ -1192,16 +1193,20 @@ rtc_library("network") { + deps += [ ":win32" ] + } + } ++} + + rtc_library("socket_address_pair") { ++if (!build_with_mozilla) { + sources = [ + "socket_address_pair.cc", + "socket_address_pair.h", + ] + deps = [ ":socket_address" ] + } ++} + + rtc_library("net_helper") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "net_helper.cc", +@@ -1210,8 +1215,10 @@ rtc_library("net_helper") { + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + deps = [ "system:rtc_export" ] + } ++} + + rtc_library("socket_adapters") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "socket_adapters.cc", +@@ -1231,6 +1238,7 @@ rtc_library("socket_adapters") { + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + } ++} + + rtc_library("network_route") { + sources = [ +@@ -1245,6 +1253,7 @@ rtc_library("network_route") { + } + + rtc_library("async_tcp_socket") { ++if (!build_with_mozilla) { + sources = [ + "async_tcp_socket.cc", + "async_tcp_socket.h", +@@ -1263,8 +1272,10 @@ rtc_library("async_tcp_socket") { + "third_party/sigslot", + ] + } ++} + + rtc_library("async_udp_socket") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "async_udp_socket.cc", +@@ -1286,8 +1297,10 @@ rtc_library("async_udp_socket") { + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + } ++} + + rtc_library("async_packet_socket") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "async_packet_socket.cc", +@@ -1305,6 +1318,7 @@ rtc_library("async_packet_socket") { + "third_party/sigslot", + ] + } ++} + + rtc_library("mdns_responder_interface") { + sources = [ "mdns_responder_interface.h" ] +@@ -1317,6 +1331,7 @@ rtc_library("dscp") { + } + + rtc_library("proxy_info") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "proxy_info.cc", +@@ -1327,6 +1342,7 @@ rtc_library("proxy_info") { + ":socket_address", + ] + } ++} + + rtc_library("file_rotating_stream") { + sources = [ +@@ -1355,6 +1371,7 @@ rtc_library("data_rate_limiter") { + } + + rtc_library("unique_id_generator") { ++if (!build_with_mozilla) { + sources = [ + "unique_id_generator.cc", + "unique_id_generator.h", +@@ -1369,6 +1386,7 @@ rtc_library("unique_id_generator") { + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + } ++} + + rtc_library("crc32") { + sources = [ +@@ -1396,6 +1414,7 @@ rtc_library("stream") { + } + + rtc_library("rtc_certificate_generator") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "rtc_certificate_generator.cc", +@@ -1413,8 +1432,10 @@ rtc_library("rtc_certificate_generator") { + "//third_party/abseil-cpp/absl/types:optional", + ] + } ++} + + rtc_library("ssl") { ++if (!build_with_mozilla) { + visibility = [ "*" ] + sources = [ + "helpers.cc", +@@ -1513,6 +1534,7 @@ rtc_library("ssl") { + deps += [ ":win32" ] + } + } ++} + + rtc_library("crypt_string") { + sources = [ +@@ -1522,6 +1544,7 @@ rtc_library("crypt_string") { + } + + rtc_library("http_common") { ++if (!build_with_mozilla) { + sources = [ + "http_common.cc", + "http_common.h", +@@ -1538,6 +1561,7 @@ rtc_library("http_common") { + + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + } ++} + + rtc_source_set("gtest_prod") { + sources = [ "gtest_prod_util.h" ] -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0089.patch b/third_party/libwebrtc/moz-patch-stack/0089.patch index 292ae24ca9f8e..fe8d05110aabe 100644 --- a/third_party/libwebrtc/moz-patch-stack/0089.patch +++ b/third_party/libwebrtc/moz-patch-stack/0089.patch @@ -1,177 +1,56 @@ -From: Michael Froman -Date: Thu, 20 Apr 2023 14:52:00 -0500 -Subject: Bug 1828517 - (fix-a138c6c8a5) handle file moves in BUILD.gn +From: Michael Froman +Date: Thu, 11 May 2023 12:02:36 -0500 +Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit b1a174041d. + r=webrtc-reviewers,mjf -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/cf7e333da17689b3c115a6ffd07fab042bc5f086 +Upstream commit: https://webrtc.googlesource.com/src/+/b1a174041ddf3057f5d6d2f87affa0f11f9413df + Relax VideoCaptureImpl::IncomingFrame size check + + When testing manually with gstreamer and v4l2loopback, the incoming + buffer is often larger than the expected size. This change allows + such frames, while still logging the error. + + Bug: webrtc:14830 + Change-Id: I399aa55af6437d75b50830166a667547f6d144d4 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291530 + Commit-Queue: Stefan Holmer + Reviewed-by: Ilya Nikolaevskiy + Reviewed-by: Stefan Holmer + Cr-Commit-Position: refs/heads/main@{#39972} + +Differential Revision: https://phabricator.services.mozilla.com/D177230 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/19b5723ad94d55e52d89aad38d5219b72ab0473e --- - rtc_base/BUILD.gn | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) + modules/video_capture/video_capture_impl.cc | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) -diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index e474ba8202..8f1be481ef 100644 ---- a/rtc_base/BUILD.gn -+++ b/rtc_base/BUILD.gn -@@ -1154,6 +1154,7 @@ if (!build_with_chromium) { - } - - rtc_library("network") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "network.cc", -@@ -1192,16 +1193,20 @@ rtc_library("network") { - deps += [ ":win32" ] +diff --git a/modules/video_capture/video_capture_impl.cc b/modules/video_capture/video_capture_impl.cc +index d227d41c34..9d9a1471e8 100644 +--- a/modules/video_capture/video_capture_impl.cc ++++ b/modules/video_capture/video_capture_impl.cc +@@ -160,11 +160,17 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame, } - } -+} - - rtc_library("socket_address_pair") { -+if (!build_with_mozilla) { - sources = [ - "socket_address_pair.cc", - "socket_address_pair.h", - ] - deps = [ ":socket_address" ] - } -+} - - rtc_library("net_helper") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "net_helper.cc", -@@ -1210,8 +1215,10 @@ rtc_library("net_helper") { - absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] - deps = [ "system:rtc_export" ] - } -+} - - rtc_library("socket_adapters") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "socket_adapters.cc", -@@ -1231,6 +1238,7 @@ rtc_library("socket_adapters") { - ] - absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] - } -+} - - rtc_library("network_route") { - sources = [ -@@ -1245,6 +1253,7 @@ rtc_library("network_route") { - } - - rtc_library("async_tcp_socket") { -+if (!build_with_mozilla) { - sources = [ - "async_tcp_socket.cc", - "async_tcp_socket.h", -@@ -1263,8 +1272,10 @@ rtc_library("async_tcp_socket") { - "third_party/sigslot", - ] - } -+} - - rtc_library("async_udp_socket") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "async_udp_socket.cc", -@@ -1286,8 +1297,10 @@ rtc_library("async_udp_socket") { - ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] - } -+} - rtc_library("async_packet_socket") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "async_packet_socket.cc", -@@ -1305,6 +1318,7 @@ rtc_library("async_packet_socket") { - "third_party/sigslot", - ] - } -+} - - rtc_library("mdns_responder_interface") { - sources = [ "mdns_responder_interface.h" ] -@@ -1317,6 +1331,7 @@ rtc_library("dscp") { - } - - rtc_library("proxy_info") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "proxy_info.cc", -@@ -1327,6 +1342,7 @@ rtc_library("proxy_info") { - ":socket_address", - ] - } -+} - - rtc_library("file_rotating_stream") { - sources = [ -@@ -1355,6 +1371,7 @@ rtc_library("data_rate_limiter") { - } - - rtc_library("unique_id_generator") { -+if (!build_with_mozilla) { - sources = [ - "unique_id_generator.cc", - "unique_id_generator.h", -@@ -1369,6 +1386,7 @@ rtc_library("unique_id_generator") { - ] - absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] - } -+} - - rtc_library("crc32") { - sources = [ -@@ -1396,6 +1414,7 @@ rtc_library("stream") { - } - - rtc_library("rtc_certificate_generator") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "rtc_certificate_generator.cc", -@@ -1413,8 +1432,10 @@ rtc_library("rtc_certificate_generator") { - "//third_party/abseil-cpp/absl/types:optional", - ] - } -+} - - rtc_library("ssl") { -+if (!build_with_mozilla) { - visibility = [ "*" ] - sources = [ - "helpers.cc", -@@ -1513,6 +1534,7 @@ rtc_library("ssl") { - deps += [ ":win32" ] + // Not encoded, convert to I420. +- if (frameInfo.videoType != VideoType::kMJPEG && +- CalcBufferSize(frameInfo.videoType, width, abs(height)) != +- videoFrameLength) { +- RTC_LOG(LS_ERROR) << "Wrong incoming frame length."; +- return -1; ++ if (frameInfo.videoType != VideoType::kMJPEG) { ++ // Allow buffers larger than expected. On linux gstreamer allocates buffers ++ // page-aligned and v4l2loopback passes us the buffer size verbatim which ++ // for most cases is larger than expected. ++ // See https://github.com/umlaeute/v4l2loopback/issues/190. ++ if (auto size = CalcBufferSize(frameInfo.videoType, width, abs(height)); ++ videoFrameLength < size) { ++ RTC_LOG(LS_ERROR) << "Wrong incoming frame length. Expected " << size ++ << ", Got " << videoFrameLength << "."; ++ return -1; ++ } } - } -+} - - rtc_library("crypt_string") { - sources = [ -@@ -1522,6 +1544,7 @@ rtc_library("crypt_string") { - } - - rtc_library("http_common") { -+if (!build_with_mozilla) { - sources = [ - "http_common.cc", - "http_common.h", -@@ -1538,6 +1561,7 @@ rtc_library("http_common") { - - absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] - } -+} - rtc_source_set("gtest_prod") { - sources = [ "gtest_prod_util.h" ] + int target_width = width; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0090.patch b/third_party/libwebrtc/moz-patch-stack/0090.patch index 9d6574033a92c..c113b33563a80 100644 --- a/third_party/libwebrtc/moz-patch-stack/0090.patch +++ b/third_party/libwebrtc/moz-patch-stack/0090.patch @@ -1,69 +1,100 @@ From: Andreas Pehrson Date: Wed, 10 May 2023 07:06:00 +0000 -Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit ba41b40461. +Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit 32b64e895c. r=webrtc-reviewers,mjf -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Upstream commit: https://webrtc.googlesource.com/src/+/ba41b40461df191624c61f0c98ae76e69fe1d46b - webrtc_libyuv: Add support for more video types for consistency +Upstream commit: https://webrtc.googlesource.com/src/+/32b64e895c0231fe6891a8f6335d66f1dad4f1f5 + Improve ergonomics of dealing with pixel formats in v4l2 camera backend Bug: webrtc:14830 - Change-Id: I0998fb04a03745131f9f5cca878b0cdb46f3b62b - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291529 - Reviewed-by: Erik SprÃ¥ng + Change-Id: Ib49bf65895fe008e75223abb03867d412c1b5a60 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291531 Commit-Queue: Ilya Nikolaevskiy + Reviewed-by: Stefan Holmer Reviewed-by: Ilya Nikolaevskiy - Cr-Commit-Position: refs/heads/main@{#39940} + Cr-Commit-Position: refs/heads/main@{#39976} -Differential Revision: https://phabricator.services.mozilla.com/D177229 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b6eaef560895caa06e11cce40083eb87fd8724a8 +Differential Revision: https://phabricator.services.mozilla.com/D177231 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/f0afe1a1097f3e02d59fd06d5e83d00a0f4d69ae --- - common_video/libyuv/include/webrtc_libyuv.h | 3 ++- - common_video/libyuv/webrtc_libyuv.cc | 4 ++++ - 2 files changed, 6 insertions(+), 1 deletion(-) + .../video_capture/linux/device_info_v4l2.cc | 4 ++- + .../video_capture/linux/video_capture_v4l2.cc | 31 +++++++++---------- + 2 files changed, 17 insertions(+), 18 deletions(-) -diff --git a/common_video/libyuv/include/webrtc_libyuv.h b/common_video/libyuv/include/webrtc_libyuv.h -index 6d9071bcd5..253a33294d 100644 ---- a/common_video/libyuv/include/webrtc_libyuv.h -+++ b/common_video/libyuv/include/webrtc_libyuv.h -@@ -32,8 +32,9 @@ enum class VideoType { - kI420, - kIYUV, - kRGB24, -- kABGR, -+ kBGR24, - kARGB, -+ kABGR, - kARGB4444, - kRGB565, - kARGB1555, -diff --git a/common_video/libyuv/webrtc_libyuv.cc b/common_video/libyuv/webrtc_libyuv.cc -index 4c6911b4a3..05a4b184c2 100644 ---- a/common_video/libyuv/webrtc_libyuv.cc -+++ b/common_video/libyuv/webrtc_libyuv.cc -@@ -39,9 +39,11 @@ size_t CalcBufferSize(VideoType type, int width, int height) { - case VideoType::kUYVY: - return width * height * 2; - case VideoType::kRGB24: -+ case VideoType::kBGR24: - return width * height * 3; - case VideoType::kBGRA: - case VideoType::kARGB: -+ case VideoType::kABGR: - return width * height * 4; - case VideoType::kMJPEG: - case VideoType::kUnknown: -@@ -93,6 +95,8 @@ int ConvertVideoType(VideoType video_type) { - return libyuv::FOURCC_YV12; - case VideoType::kRGB24: - return libyuv::FOURCC_24BG; -+ case VideoType::kBGR24: -+ return libyuv::FOURCC_RAW; - case VideoType::kABGR: - return libyuv::FOURCC_ABGR; - case VideoType::kRGB565: +diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc +index 7651dd6651..f854c2ccc7 100644 +--- a/modules/video_capture/linux/device_info_v4l2.cc ++++ b/modules/video_capture/linux/device_info_v4l2.cc +@@ -391,10 +391,10 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { + video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + video_fmt.fmt.pix.sizeimage = 0; + +- int totalFmts = 5; + unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, + V4L2_PIX_FMT_NV12}; ++ constexpr int totalFmts = sizeof(videoFormats) / sizeof(unsigned int); + + int sizes = 13; + unsigned int size[][2] = {{128, 96}, {160, 120}, {176, 144}, {320, 240}, +@@ -424,6 +424,8 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { + cap.videoType = VideoType::kUYVY; + } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { + cap.videoType = VideoType::kNV12; ++ } else { ++ RTC_DCHECK_NOTREACHED(); + } + + // get fps of current camera mode +diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc +index c7dcb722bc..baf1916331 100644 +--- a/modules/video_capture/linux/video_capture_v4l2.cc ++++ b/modules/video_capture/linux/video_capture_v4l2.cc +@@ -130,23 +130,18 @@ int32_t VideoCaptureModuleV4L2::StartCapture( + // Supported video formats in preferred order. + // If the requested resolution is larger than VGA, we prefer MJPEG. Go for + // I420 otherwise. +- const int nFormats = 6; +- unsigned int fmts[nFormats]; +- if (capability.width > 640 || capability.height > 480) { +- fmts[0] = V4L2_PIX_FMT_MJPEG; +- fmts[1] = V4L2_PIX_FMT_YUV420; +- fmts[2] = V4L2_PIX_FMT_YUYV; +- fmts[3] = V4L2_PIX_FMT_UYVY; +- fmts[4] = V4L2_PIX_FMT_NV12; +- fmts[5] = V4L2_PIX_FMT_JPEG; +- } else { +- fmts[0] = V4L2_PIX_FMT_YUV420; +- fmts[1] = V4L2_PIX_FMT_YUYV; +- fmts[2] = V4L2_PIX_FMT_UYVY; +- fmts[3] = V4L2_PIX_FMT_NV12; +- fmts[4] = V4L2_PIX_FMT_MJPEG; +- fmts[5] = V4L2_PIX_FMT_JPEG; +- } ++ unsigned int hdFmts[] = { ++ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, ++ V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_JPEG, ++ }; ++ unsigned int sdFmts[] = { ++ V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, ++ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, ++ }; ++ const bool isHd = capability.width > 640 || capability.height > 480; ++ unsigned int* fmts = isHd ? hdFmts : sdFmts; ++ static_assert(sizeof(hdFmts) == sizeof(sdFmts)); ++ constexpr int nFormats = sizeof(hdFmts) / sizeof(unsigned int); + + // Enumerate image formats. + struct v4l2_fmtdesc fmt; +@@ -195,6 +190,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture( + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || + video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) + _captureVideoType = VideoType::kMJPEG; ++ else ++ RTC_DCHECK_NOTREACHED(); + + // set format and frame size now + if (ioctl(_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) { -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0091.patch b/third_party/libwebrtc/moz-patch-stack/0091.patch index fe8d05110aabe..9eca10032f5fd 100644 --- a/third_party/libwebrtc/moz-patch-stack/0091.patch +++ b/third_party/libwebrtc/moz-patch-stack/0091.patch @@ -1,56 +1,238 @@ -From: Michael Froman -Date: Thu, 11 May 2023 12:02:36 -0500 -Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit b1a174041d. +From: Andreas Pehrson +Date: Wed, 10 May 2023 07:06:00 +0000 +Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit 91d5fc2ed6. r=webrtc-reviewers,mjf -Upstream commit: https://webrtc.googlesource.com/src/+/b1a174041ddf3057f5d6d2f87affa0f11f9413df - Relax VideoCaptureImpl::IncomingFrame size check +Upstream commit: https://webrtc.googlesource.com/src/+/91d5fc2ed6ef347d90182868320267d45cf9525b + Support more pixel formats in v4l2 camera backend - When testing manually with gstreamer and v4l2loopback, the incoming - buffer is often larger than the expected size. This change allows - such frames, while still logging the error. + These were tested with gstreamer and v4l2loopback, example setup: + $ sudo v4l2loopback-ctl add -n BGRA 10 + $ gst-launch-1.0 videotestsrc pattern=smpte-rp-219 ! \ + video/x-raw,format=BGRA ! v4l2sink device=/dev/video10 > /dev/null & + + Then conversion was confirmed with video_loopback: + $ ./video_loopback --capture_device_index=3 --logs 2>&1 | grep -i \ + capture Bug: webrtc:14830 - Change-Id: I399aa55af6437d75b50830166a667547f6d144d4 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291530 + Change-Id: I35c8e453cf7f9a2923935b0ad82477a3144e8c12 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291532 Commit-Queue: Stefan Holmer - Reviewed-by: Ilya Nikolaevskiy + Reviewed-by: Mirko Bonadei Reviewed-by: Stefan Holmer - Cr-Commit-Position: refs/heads/main@{#39972} + Cr-Commit-Position: refs/heads/main@{#39979} -Differential Revision: https://phabricator.services.mozilla.com/D177230 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/19b5723ad94d55e52d89aad38d5219b72ab0473e +Differential Revision: https://phabricator.services.mozilla.com/D177232 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/92dc582fdcf3a2fdb3fcdbcd96080d081de8f8d5 --- - modules/video_capture/video_capture_impl.cc | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) + .../video_capture/linux/device_info_v4l2.cc | 71 +++++++++++++++++-- + .../video_capture/linux/video_capture_v4l2.cc | 63 ++++++++++++++-- + 2 files changed, 126 insertions(+), 8 deletions(-) -diff --git a/modules/video_capture/video_capture_impl.cc b/modules/video_capture/video_capture_impl.cc -index d227d41c34..9d9a1471e8 100644 ---- a/modules/video_capture/video_capture_impl.cc -+++ b/modules/video_capture/video_capture_impl.cc -@@ -160,11 +160,17 @@ int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame, - } +diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc +index f854c2ccc7..ccd4b2bd2a 100644 +--- a/modules/video_capture/linux/device_info_v4l2.cc ++++ b/modules/video_capture/linux/device_info_v4l2.cc +@@ -39,6 +39,24 @@ + #define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) + #endif + ++// These defines are here to support building on kernel 3.16 which some ++// downstream projects, e.g. Firefox, use. ++// TODO(apehrson): Remove them and their undefs when no longer needed. ++#ifndef V4L2_PIX_FMT_ABGR32 ++#define ABGR32_OVERRIDE 1 ++#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') ++#endif ++ ++#ifndef V4L2_PIX_FMT_ARGB32 ++#define ARGB32_OVERRIDE 1 ++#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') ++#endif ++ ++#ifndef V4L2_PIX_FMT_RGBA32 ++#define RGBA32_OVERRIDE 1 ++#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') ++#endif ++ + namespace webrtc { + namespace videocapturemodule { + #ifdef WEBRTC_LINUX +@@ -391,9 +409,13 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { + video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + video_fmt.fmt.pix.sizeimage = 0; + +- unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, +- V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, +- V4L2_PIX_FMT_NV12}; ++ unsigned int videoFormats[] = { ++ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420, ++ V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, ++ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, ++ V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_ARGB32, ++ V4L2_PIX_FMT_RGBA32, V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_RGB32, ++ }; + constexpr int totalFmts = sizeof(videoFormats) / sizeof(unsigned int); + + int sizes = 13; +@@ -418,12 +440,38 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { + cap.videoType = VideoType::kYUY2; + } else if (videoFormats[fmts] == V4L2_PIX_FMT_YUV420) { + cap.videoType = VideoType::kI420; +- } else if (videoFormats[fmts] == V4L2_PIX_FMT_MJPEG) { ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_YVU420) { ++ cap.videoType = VideoType::kYV12; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_MJPEG || ++ videoFormats[fmts] == V4L2_PIX_FMT_JPEG) { + cap.videoType = VideoType::kMJPEG; + } else if (videoFormats[fmts] == V4L2_PIX_FMT_UYVY) { + cap.videoType = VideoType::kUYVY; + } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { + cap.videoType = VideoType::kNV12; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_BGR24) { ++ // NB that for RGB formats, `VideoType` follows naming conventions ++ // of libyuv[1], where e.g. the format for FOURCC "ARGB" stores ++ // pixels in BGRA order in memory. V4L2[2] on the other hand names ++ // its formats based on the order of the RGB components as stored in ++ // memory. Applies to all RGB formats below. ++ // [1]https://chromium.googlesource.com/libyuv/libyuv/+/refs/heads/main/docs/formats.md#the-argb-fourcc ++ // [2]https://www.kernel.org/doc/html/v6.2/userspace-api/media/v4l/pixfmt-rgb.html#bits-per-component ++ cap.videoType = VideoType::kRGB24; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB24) { ++ cap.videoType = VideoType::kBGR24; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB565) { ++ cap.videoType = VideoType::kRGB565; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_ABGR32) { ++ cap.videoType = VideoType::kARGB; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_ARGB32) { ++ cap.videoType = VideoType::kBGRA; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_BGR32) { ++ cap.videoType = VideoType::kARGB; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB32) { ++ cap.videoType = VideoType::kBGRA; ++ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGBA32) { ++ cap.videoType = VideoType::kABGR; + } else { + RTC_DCHECK_NOTREACHED(); + } +@@ -452,3 +500,18 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { - // Not encoded, convert to I420. -- if (frameInfo.videoType != VideoType::kMJPEG && -- CalcBufferSize(frameInfo.videoType, width, abs(height)) != -- videoFrameLength) { -- RTC_LOG(LS_ERROR) << "Wrong incoming frame length."; -- return -1; -+ if (frameInfo.videoType != VideoType::kMJPEG) { -+ // Allow buffers larger than expected. On linux gstreamer allocates buffers -+ // page-aligned and v4l2loopback passes us the buffer size verbatim which -+ // for most cases is larger than expected. -+ // See https://github.com/umlaeute/v4l2loopback/issues/190. -+ if (auto size = CalcBufferSize(frameInfo.videoType, width, abs(height)); -+ videoFrameLength < size) { -+ RTC_LOG(LS_ERROR) << "Wrong incoming frame length. Expected " << size -+ << ", Got " << videoFrameLength << "."; -+ return -1; -+ } - } + } // namespace videocapturemodule + } // namespace webrtc ++ ++#ifdef ABGR32_OVERRIDE ++#undef ABGR32_OVERRIDE ++#undef V4L2_PIX_FMT_ABGR32 ++#endif ++ ++#ifdef ARGB32_OVERRIDE ++#undef ARGB32_OVERRIDE ++#undef V4L2_PIX_FMT_ARGB32 ++#endif ++ ++#ifdef RGBA32_OVERRIDE ++#undef RGBA32_OVERRIDE ++#undef V4L2_PIX_FMT_RGBA32 ++#endif +diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc +index baf1916331..2935cd027d 100644 +--- a/modules/video_capture/linux/video_capture_v4l2.cc ++++ b/modules/video_capture/linux/video_capture_v4l2.cc +@@ -37,6 +37,24 @@ + #include "modules/video_capture/video_capture.h" + #include "rtc_base/logging.h" - int target_width = width; ++// These defines are here to support building on kernel 3.16 which some ++// downstream projects, e.g. Firefox, use. ++// TODO(apehrson): Remove them and their undefs when no longer needed. ++#ifndef V4L2_PIX_FMT_ABGR32 ++#define ABGR32_OVERRIDE 1 ++#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') ++#endif ++ ++#ifndef V4L2_PIX_FMT_ARGB32 ++#define ARGB32_OVERRIDE 1 ++#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') ++#endif ++ ++#ifndef V4L2_PIX_FMT_RGBA32 ++#define RGBA32_OVERRIDE 1 ++#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') ++#endif ++ + namespace webrtc { + namespace videocapturemodule { + VideoCaptureModuleV4L2::VideoCaptureModuleV4L2() +@@ -131,12 +149,18 @@ int32_t VideoCaptureModuleV4L2::StartCapture( + // If the requested resolution is larger than VGA, we prefer MJPEG. Go for + // I420 otherwise. + unsigned int hdFmts[] = { +- V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, +- V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_JPEG, ++ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, ++ V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, ++ V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32, ++ V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_BGR24, ++ V4L2_PIX_FMT_RGB24, V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_JPEG, + }; + unsigned int sdFmts[] = { +- V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, +- V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, ++ V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV, ++ V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_ABGR32, ++ V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32, V4L2_PIX_FMT_BGR32, ++ V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, ++ V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, + }; + const bool isHd = capability.width > 640 || capability.height > 480; + unsigned int* fmts = isHd ? hdFmts : sdFmts; +@@ -183,10 +207,26 @@ int32_t VideoCaptureModuleV4L2::StartCapture( + _captureVideoType = VideoType::kYUY2; + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) + _captureVideoType = VideoType::kI420; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) ++ _captureVideoType = VideoType::kYV12; + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) + _captureVideoType = VideoType::kUYVY; + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) + _captureVideoType = VideoType::kNV12; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) ++ _captureVideoType = VideoType::kRGB24; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) ++ _captureVideoType = VideoType::kBGR24; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) ++ _captureVideoType = VideoType::kRGB565; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ABGR32 || ++ video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) ++ _captureVideoType = VideoType::kARGB; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ARGB32 || ++ video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) ++ _captureVideoType = VideoType::kBGRA; ++ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGBA32) ++ _captureVideoType = VideoType::kABGR; + else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || + video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) + _captureVideoType = VideoType::kMJPEG; +@@ -432,3 +472,18 @@ int32_t VideoCaptureModuleV4L2::CaptureSettings( + } + } // namespace videocapturemodule + } // namespace webrtc ++ ++#ifdef ABGR32_OVERRIDE ++#undef ABGR32_OVERRIDE ++#undef V4L2_PIX_FMT_ABGR32 ++#endif ++ ++#ifdef ARGB32_OVERRIDE ++#undef ARGB32_OVERRIDE ++#undef V4L2_PIX_FMT_ARGB32 ++#endif ++ ++#ifdef RGBA32_OVERRIDE ++#undef RGBA32_OVERRIDE ++#undef V4L2_PIX_FMT_RGBA32 ++#endif -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0092.patch b/third_party/libwebrtc/moz-patch-stack/0092.patch index c113b33563a80..e7fc0e79a8171 100644 --- a/third_party/libwebrtc/moz-patch-stack/0092.patch +++ b/third_party/libwebrtc/moz-patch-stack/0092.patch @@ -1,100 +1,115 @@ From: Andreas Pehrson -Date: Wed, 10 May 2023 07:06:00 +0000 -Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit 32b64e895c. - r=webrtc-reviewers,mjf +Date: Wed, 26 Apr 2023 19:45:00 +0000 +Subject: Bug 1694304 - cherry-pick libwebrtc 28ac56a415. + r=webrtc-reviewers,jib -Upstream commit: https://webrtc.googlesource.com/src/+/32b64e895c0231fe6891a8f6335d66f1dad4f1f5 - Improve ergonomics of dealing with pixel formats in v4l2 camera backend +Upstream commit: https://webrtc.googlesource.com/src/+/28ac56a415a7513f1ebfb985659bf2012d84df3f + In VideoCaptureDS::Stop() fully stop the device - Bug: webrtc:14830 - Change-Id: Ib49bf65895fe008e75223abb03867d412c1b5a60 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291531 + This makes the device light turn off when stopped. + + Bug: webrtc:15109 + Change-Id: I1deecbc2463e2e316e01ff1f061ab6b0313c1aa1 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/302200 Commit-Queue: Ilya Nikolaevskiy - Reviewed-by: Stefan Holmer Reviewed-by: Ilya Nikolaevskiy - Cr-Commit-Position: refs/heads/main@{#39976} + Reviewed-by: Per Kjellander + Cr-Commit-Position: refs/heads/main@{#39953} -Differential Revision: https://phabricator.services.mozilla.com/D177231 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/f0afe1a1097f3e02d59fd06d5e83d00a0f4d69ae +Differential Revision: https://phabricator.services.mozilla.com/D176507 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/dabb9e2ec9d3b77e4cc19de0fb98cae4ce88293d --- - .../video_capture/linux/device_info_v4l2.cc | 4 ++- - .../video_capture/linux/video_capture_v4l2.cc | 31 +++++++++---------- - 2 files changed, 17 insertions(+), 18 deletions(-) + .../test/video_capture_unittest.cc | 33 +++++++++++++++++++ + .../video_capture/windows/video_capture_ds.cc | 18 +++++----- + 2 files changed, 41 insertions(+), 10 deletions(-) -diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc -index 7651dd6651..f854c2ccc7 100644 ---- a/modules/video_capture/linux/device_info_v4l2.cc -+++ b/modules/video_capture/linux/device_info_v4l2.cc -@@ -391,10 +391,10 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { - video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - video_fmt.fmt.pix.sizeimage = 0; - -- int totalFmts = 5; - unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, - V4L2_PIX_FMT_NV12}; -+ constexpr int totalFmts = sizeof(videoFormats) / sizeof(unsigned int); +diff --git a/modules/video_capture/test/video_capture_unittest.cc b/modules/video_capture/test/video_capture_unittest.cc +index 4cf3d5931c..c8af222b57 100644 +--- a/modules/video_capture/test/video_capture_unittest.cc ++++ b/modules/video_capture/test/video_capture_unittest.cc +@@ -341,3 +341,36 @@ TEST_F(VideoCaptureTest, DISABLED_TestTwoCameras) { + EXPECT_EQ(0, module2->StopCapture()); + EXPECT_EQ(0, module1->StopCapture()); + } ++ ++#ifdef WEBRTC_MAC ++// No VideoCaptureImpl on Mac. ++#define MAYBE_ConcurrentAccess DISABLED_ConcurrentAccess ++#else ++#define MAYBE_ConcurrentAccess ConcurrentAccess ++#endif ++TEST_F(VideoCaptureTest, MAYBE_ConcurrentAccess) { ++ TestVideoCaptureCallback capture_observer1; ++ rtc::scoped_refptr module1( ++ OpenVideoCaptureDevice(0, &capture_observer1)); ++ ASSERT_TRUE(module1.get() != NULL); ++ VideoCaptureCapability capability; ++ device_info_->GetCapability(module1->CurrentDeviceName(), 0, capability); ++ capture_observer1.SetExpectedCapability(capability); ++ ++ TestVideoCaptureCallback capture_observer2; ++ rtc::scoped_refptr module2( ++ OpenVideoCaptureDevice(0, &capture_observer2)); ++ ASSERT_TRUE(module2.get() != NULL); ++ capture_observer2.SetExpectedCapability(capability); ++ ++ // Starting module1 should work. ++ ASSERT_NO_FATAL_FAILURE(StartCapture(module1.get(), capability)); ++ EXPECT_TRUE_WAIT(capture_observer1.incoming_frames() >= 5, kTimeOut); ++ ++ // When module1 is stopped, starting module2 for the same device should work. ++ EXPECT_EQ(0, module1->StopCapture()); ++ ASSERT_NO_FATAL_FAILURE(StartCapture(module2.get(), capability)); ++ EXPECT_TRUE_WAIT(capture_observer2.incoming_frames() >= 5, kTimeOut); ++ ++ EXPECT_EQ(0, module2->StopCapture()); ++} +diff --git a/modules/video_capture/windows/video_capture_ds.cc b/modules/video_capture/windows/video_capture_ds.cc +index 74b31d98be..8695f76245 100644 +--- a/modules/video_capture/windows/video_capture_ds.cc ++++ b/modules/video_capture/windows/video_capture_ds.cc +@@ -113,17 +113,9 @@ int32_t VideoCaptureDS::Init(const char* deviceUniqueIdUTF8) { + return -1; + } - int sizes = 13; - unsigned int size[][2] = {{128, 96}, {160, 120}, {176, 144}, {320, 240}, -@@ -424,6 +424,8 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { - cap.videoType = VideoType::kUYVY; - } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { - cap.videoType = VideoType::kNV12; -+ } else { -+ RTC_DCHECK_NOTREACHED(); - } - - // get fps of current camera mode -diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc -index c7dcb722bc..baf1916331 100644 ---- a/modules/video_capture/linux/video_capture_v4l2.cc -+++ b/modules/video_capture/linux/video_capture_v4l2.cc -@@ -130,23 +130,18 @@ int32_t VideoCaptureModuleV4L2::StartCapture( - // Supported video formats in preferred order. - // If the requested resolution is larger than VGA, we prefer MJPEG. Go for - // I420 otherwise. -- const int nFormats = 6; -- unsigned int fmts[nFormats]; -- if (capability.width > 640 || capability.height > 480) { -- fmts[0] = V4L2_PIX_FMT_MJPEG; -- fmts[1] = V4L2_PIX_FMT_YUV420; -- fmts[2] = V4L2_PIX_FMT_YUYV; -- fmts[3] = V4L2_PIX_FMT_UYVY; -- fmts[4] = V4L2_PIX_FMT_NV12; -- fmts[5] = V4L2_PIX_FMT_JPEG; -- } else { -- fmts[0] = V4L2_PIX_FMT_YUV420; -- fmts[1] = V4L2_PIX_FMT_YUYV; -- fmts[2] = V4L2_PIX_FMT_UYVY; -- fmts[3] = V4L2_PIX_FMT_NV12; -- fmts[4] = V4L2_PIX_FMT_MJPEG; -- fmts[5] = V4L2_PIX_FMT_JPEG; +- // Temporary connect here. +- // This is done so that no one else can use the capture device. + if (SetCameraOutput(_requestedCapability) != 0) { + return -1; + } +- hr = _mediaControl->Pause(); +- if (FAILED(hr)) { +- RTC_LOG(LS_INFO) +- << "Failed to Pause the Capture device. Is it already occupied? " << hr; +- return -1; - } -+ unsigned int hdFmts[] = { -+ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, -+ V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_JPEG, -+ }; -+ unsigned int sdFmts[] = { -+ V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, -+ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, -+ }; -+ const bool isHd = capability.width > 640 || capability.height > 480; -+ unsigned int* fmts = isHd ? hdFmts : sdFmts; -+ static_assert(sizeof(hdFmts) == sizeof(sdFmts)); -+ constexpr int nFormats = sizeof(hdFmts) / sizeof(unsigned int); - - // Enumerate image formats. - struct v4l2_fmtdesc fmt; -@@ -195,6 +190,8 @@ int32_t VideoCaptureModuleV4L2::StartCapture( - else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || - video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) - _captureVideoType = VideoType::kMJPEG; -+ else -+ RTC_DCHECK_NOTREACHED(); + RTC_LOG(LS_INFO) << "Capture device '" << deviceUniqueIdUTF8 + << "' initialized."; + return 0; +@@ -139,7 +131,13 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { + return -1; + } + } +- HRESULT hr = _mediaControl->Run(); ++ HRESULT hr = _mediaControl->Pause(); ++ if (FAILED(hr)) { ++ RTC_LOG(LS_INFO) ++ << "Failed to Pause the Capture device. Is it already occupied? " << hr; ++ return -1; ++ } ++ hr = _mediaControl->Run(); + if (FAILED(hr)) { + RTC_LOG(LS_INFO) << "Failed to start the Capture device."; + return -1; +@@ -150,7 +148,7 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { + int32_t VideoCaptureDS::StopCapture() { + MutexLock lock(&api_lock_); - // set format and frame size now - if (ioctl(_deviceFd, VIDIOC_S_FMT, &video_fmt) < 0) { +- HRESULT hr = _mediaControl->Pause(); ++ HRESULT hr = _mediaControl->StopWhenReady(); + if (FAILED(hr)) { + RTC_LOG(LS_INFO) << "Failed to stop the capture graph. " << hr; + return -1; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0093.patch b/third_party/libwebrtc/moz-patch-stack/0093.patch index 9eca10032f5fd..c2dfc82f60e81 100644 --- a/third_party/libwebrtc/moz-patch-stack/0093.patch +++ b/third_party/libwebrtc/moz-patch-stack/0093.patch @@ -1,238 +1,71 @@ From: Andreas Pehrson -Date: Wed, 10 May 2023 07:06:00 +0000 -Subject: Bug 1810949 - cherry-pick upstream libwebrtc commit 91d5fc2ed6. +Date: Wed, 10 May 2023 08:01:00 +0000 +Subject: Bug 1828065 - cherry-pick upstream libwebrtc commit 6fc1ae58be. r=webrtc-reviewers,mjf -Upstream commit: https://webrtc.googlesource.com/src/+/91d5fc2ed6ef347d90182868320267d45cf9525b - Support more pixel formats in v4l2 camera backend +Upstream commit: https://webrtc.googlesource.com/src/+/6fc1ae58be7cbb61ad0431d90eb7a7dc333de2f2 + In DeviceInfoDS check that out vars were set - These were tested with gstreamer and v4l2loopback, example setup: - $ sudo v4l2loopback-ctl add -n BGRA 10 - $ gst-launch-1.0 videotestsrc pattern=smpte-rp-219 ! \ - video/x-raw,format=BGRA ! v4l2sink device=/dev/video10 > /dev/null & + Bug: chromium:1441804 + Change-Id: Id07cb61519315d77c2d7cdab1053efaaf7473e1a + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304060 + Reviewed-by: Ilya Nikolaevskiy + Reviewed-by: Per Kjellander + Commit-Queue: Ilya Nikolaevskiy + Cr-Commit-Position: refs/heads/main@{#39982} - Then conversion was confirmed with video_loopback: - $ ./video_loopback --capture_device_index=3 --logs 2>&1 | grep -i \ - capture - - Bug: webrtc:14830 - Change-Id: I35c8e453cf7f9a2923935b0ad82477a3144e8c12 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/291532 - Commit-Queue: Stefan Holmer - Reviewed-by: Mirko Bonadei - Reviewed-by: Stefan Holmer - Cr-Commit-Position: refs/heads/main@{#39979} - -Differential Revision: https://phabricator.services.mozilla.com/D177232 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/92dc582fdcf3a2fdb3fcdbcd96080d081de8f8d5 +Differential Revision: https://phabricator.services.mozilla.com/D177236 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/60d381b6016ae5af0181b44c6a31b41eab094793 --- - .../video_capture/linux/device_info_v4l2.cc | 71 +++++++++++++++++-- - .../video_capture/linux/video_capture_v4l2.cc | 63 ++++++++++++++-- - 2 files changed, 126 insertions(+), 8 deletions(-) + modules/video_capture/windows/device_info_ds.cc | 13 +++++++------ + modules/video_capture/windows/help_functions_ds.cc | 3 +++ + 2 files changed, 10 insertions(+), 6 deletions(-) -diff --git a/modules/video_capture/linux/device_info_v4l2.cc b/modules/video_capture/linux/device_info_v4l2.cc -index f854c2ccc7..ccd4b2bd2a 100644 ---- a/modules/video_capture/linux/device_info_v4l2.cc -+++ b/modules/video_capture/linux/device_info_v4l2.cc -@@ -39,6 +39,24 @@ - #define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) - #endif - -+// These defines are here to support building on kernel 3.16 which some -+// downstream projects, e.g. Firefox, use. -+// TODO(apehrson): Remove them and their undefs when no longer needed. -+#ifndef V4L2_PIX_FMT_ABGR32 -+#define ABGR32_OVERRIDE 1 -+#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') -+#endif -+ -+#ifndef V4L2_PIX_FMT_ARGB32 -+#define ARGB32_OVERRIDE 1 -+#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') -+#endif -+ -+#ifndef V4L2_PIX_FMT_RGBA32 -+#define RGBA32_OVERRIDE 1 -+#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') -+#endif -+ - namespace webrtc { - namespace videocapturemodule { - #ifdef WEBRTC_LINUX -@@ -391,9 +409,13 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { - video_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - video_fmt.fmt.pix.sizeimage = 0; - -- unsigned int videoFormats[] = {V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, -- V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, -- V4L2_PIX_FMT_NV12}; -+ unsigned int videoFormats[] = { -+ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420, -+ V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, -+ V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, -+ V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_ARGB32, -+ V4L2_PIX_FMT_RGBA32, V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_RGB32, -+ }; - constexpr int totalFmts = sizeof(videoFormats) / sizeof(unsigned int); - - int sizes = 13; -@@ -418,12 +440,38 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { - cap.videoType = VideoType::kYUY2; - } else if (videoFormats[fmts] == V4L2_PIX_FMT_YUV420) { - cap.videoType = VideoType::kI420; -- } else if (videoFormats[fmts] == V4L2_PIX_FMT_MJPEG) { -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_YVU420) { -+ cap.videoType = VideoType::kYV12; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_MJPEG || -+ videoFormats[fmts] == V4L2_PIX_FMT_JPEG) { - cap.videoType = VideoType::kMJPEG; - } else if (videoFormats[fmts] == V4L2_PIX_FMT_UYVY) { - cap.videoType = VideoType::kUYVY; - } else if (videoFormats[fmts] == V4L2_PIX_FMT_NV12) { - cap.videoType = VideoType::kNV12; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_BGR24) { -+ // NB that for RGB formats, `VideoType` follows naming conventions -+ // of libyuv[1], where e.g. the format for FOURCC "ARGB" stores -+ // pixels in BGRA order in memory. V4L2[2] on the other hand names -+ // its formats based on the order of the RGB components as stored in -+ // memory. Applies to all RGB formats below. -+ // [1]https://chromium.googlesource.com/libyuv/libyuv/+/refs/heads/main/docs/formats.md#the-argb-fourcc -+ // [2]https://www.kernel.org/doc/html/v6.2/userspace-api/media/v4l/pixfmt-rgb.html#bits-per-component -+ cap.videoType = VideoType::kRGB24; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB24) { -+ cap.videoType = VideoType::kBGR24; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB565) { -+ cap.videoType = VideoType::kRGB565; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_ABGR32) { -+ cap.videoType = VideoType::kARGB; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_ARGB32) { -+ cap.videoType = VideoType::kBGRA; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_BGR32) { -+ cap.videoType = VideoType::kARGB; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGB32) { -+ cap.videoType = VideoType::kBGRA; -+ } else if (videoFormats[fmts] == V4L2_PIX_FMT_RGBA32) { -+ cap.videoType = VideoType::kABGR; - } else { - RTC_DCHECK_NOTREACHED(); - } -@@ -452,3 +500,18 @@ int32_t DeviceInfoV4l2::FillCapabilities(int fd) { +diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc +index 299be99502..b5867923d1 100644 +--- a/modules/video_capture/windows/device_info_ds.cc ++++ b/modules/video_capture/windows/device_info_ds.cc +@@ -504,9 +504,9 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) + } - } // namespace videocapturemodule - } // namespace webrtc -+ -+#ifdef ABGR32_OVERRIDE -+#undef ABGR32_OVERRIDE -+#undef V4L2_PIX_FMT_ABGR32 -+#endif -+ -+#ifdef ARGB32_OVERRIDE -+#undef ARGB32_OVERRIDE -+#undef V4L2_PIX_FMT_ARGB32 -+#endif -+ -+#ifdef RGBA32_OVERRIDE -+#undef RGBA32_OVERRIDE -+#undef V4L2_PIX_FMT_RGBA32 -+#endif -diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc -index baf1916331..2935cd027d 100644 ---- a/modules/video_capture/linux/video_capture_v4l2.cc -+++ b/modules/video_capture/linux/video_capture_v4l2.cc -@@ -37,6 +37,24 @@ - #include "modules/video_capture/video_capture.h" - #include "rtc_base/logging.h" + if (hrVC == S_OK) { +- LONGLONG* frameDurationList; +- LONGLONG maxFPS; +- long listSize; ++ LONGLONG* frameDurationList = NULL; ++ LONGLONG maxFPS = 0; ++ long listSize = 0; + SIZE size; + size.cx = capability.width; + size.cy = capability.height; +@@ -519,9 +519,10 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) + hrVC = videoControlConfig->GetFrameRateList( + outputCapturePin, tmp, size, &listSize, &frameDurationList); -+// These defines are here to support building on kernel 3.16 which some -+// downstream projects, e.g. Firefox, use. -+// TODO(apehrson): Remove them and their undefs when no longer needed. -+#ifndef V4L2_PIX_FMT_ABGR32 -+#define ABGR32_OVERRIDE 1 -+#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') -+#endif -+ -+#ifndef V4L2_PIX_FMT_ARGB32 -+#define ARGB32_OVERRIDE 1 -+#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') -+#endif -+ -+#ifndef V4L2_PIX_FMT_RGBA32 -+#define RGBA32_OVERRIDE 1 -+#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') -+#endif -+ - namespace webrtc { +- // On some odd cameras, you may get a 0 for duration. +- // GetMaxOfFrameArray returns the lowest duration (highest FPS) +- if (hrVC == S_OK && listSize > 0 && ++ // On some odd cameras, you may get a 0 for duration. Some others may ++ // not update the out vars. GetMaxOfFrameArray returns the lowest ++ // duration (highest FPS), or 0 if there was no list with elements. ++ if (hrVC == S_OK && + 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, listSize))) { + capability.maxFPS = static_cast(10000000 / maxFPS); + capability.supportFrameRateControl = true; +diff --git a/modules/video_capture/windows/help_functions_ds.cc b/modules/video_capture/windows/help_functions_ds.cc +index b767726107..47fecfe4a1 100644 +--- a/modules/video_capture/windows/help_functions_ds.cc ++++ b/modules/video_capture/windows/help_functions_ds.cc +@@ -21,6 +21,9 @@ namespace webrtc { namespace videocapturemodule { - VideoCaptureModuleV4L2::VideoCaptureModuleV4L2() -@@ -131,12 +149,18 @@ int32_t VideoCaptureModuleV4L2::StartCapture( - // If the requested resolution is larger than VGA, we prefer MJPEG. Go for - // I420 otherwise. - unsigned int hdFmts[] = { -- V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, -- V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_JPEG, -+ V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, -+ V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, -+ V4L2_PIX_FMT_ABGR32, V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32, -+ V4L2_PIX_FMT_BGR32, V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_BGR24, -+ V4L2_PIX_FMT_RGB24, V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_JPEG, - }; - unsigned int sdFmts[] = { -- V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_UYVY, -- V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, -+ V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_YVU420, V4L2_PIX_FMT_YUYV, -+ V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_ABGR32, -+ V4L2_PIX_FMT_ARGB32, V4L2_PIX_FMT_RGBA32, V4L2_PIX_FMT_BGR32, -+ V4L2_PIX_FMT_RGB32, V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24, -+ V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_JPEG, - }; - const bool isHd = capability.width > 640 || capability.height > 480; - unsigned int* fmts = isHd ? hdFmts : sdFmts; -@@ -183,10 +207,26 @@ int32_t VideoCaptureModuleV4L2::StartCapture( - _captureVideoType = VideoType::kYUY2; - else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) - _captureVideoType = VideoType::kI420; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) -+ _captureVideoType = VideoType::kYV12; - else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) - _captureVideoType = VideoType::kUYVY; - else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) - _captureVideoType = VideoType::kNV12; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) -+ _captureVideoType = VideoType::kRGB24; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) -+ _captureVideoType = VideoType::kBGR24; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) -+ _captureVideoType = VideoType::kRGB565; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ABGR32 || -+ video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) -+ _captureVideoType = VideoType::kARGB; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_ARGB32 || -+ video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) -+ _captureVideoType = VideoType::kBGRA; -+ else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_RGBA32) -+ _captureVideoType = VideoType::kABGR; - else if (video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG || - video_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG) - _captureVideoType = VideoType::kMJPEG; -@@ -432,3 +472,18 @@ int32_t VideoCaptureModuleV4L2::CaptureSettings( - } - } // namespace videocapturemodule - } // namespace webrtc -+ -+#ifdef ABGR32_OVERRIDE -+#undef ABGR32_OVERRIDE -+#undef V4L2_PIX_FMT_ABGR32 -+#endif -+ -+#ifdef ARGB32_OVERRIDE -+#undef ARGB32_OVERRIDE -+#undef V4L2_PIX_FMT_ARGB32 -+#endif -+ -+#ifdef RGBA32_OVERRIDE -+#undef RGBA32_OVERRIDE -+#undef V4L2_PIX_FMT_RGBA32 -+#endif + // This returns minimum :), which will give max frame rate... + LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size) { ++ if (!maxFps || size <= 0) { ++ return 0; ++ } + LONGLONG maxFPS = maxFps[0]; + for (int i = 0; i < size; i++) { + if (maxFPS > maxFps[i]) -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0094.patch b/third_party/libwebrtc/moz-patch-stack/0094.patch index e7fc0e79a8171..00136f3eb4564 100644 --- a/third_party/libwebrtc/moz-patch-stack/0094.patch +++ b/third_party/libwebrtc/moz-patch-stack/0094.patch @@ -1,115 +1,52 @@ From: Andreas Pehrson -Date: Wed, 26 Apr 2023 19:45:00 +0000 -Subject: Bug 1694304 - cherry-pick libwebrtc 28ac56a415. - r=webrtc-reviewers,jib +Date: Wed, 10 May 2023 08:01:00 +0000 +Subject: Bug 1828065 - cherry-pick upstream libwebrtc commit adf55790b6. + r=webrtc-reviewers,mjf -Upstream commit: https://webrtc.googlesource.com/src/+/28ac56a415a7513f1ebfb985659bf2012d84df3f - In VideoCaptureDS::Stop() fully stop the device +Upstream commit: https://webrtc.googlesource.com/src/+/adf55790b6ecf50c4bb2b2cf7d58441303b9d946 + In DeviceInfoDS free the frame duration list after use - This makes the device light turn off when stopped. + Per the docs, the caller is responsible for freeing the memory. - Bug: webrtc:15109 - Change-Id: I1deecbc2463e2e316e01ff1f061ab6b0313c1aa1 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/302200 + Bug: chromium:1441804 + Change-Id: I9aaae493a1a86d8ab4f03930715a643a3c9fb61b + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304061 + Reviewed-by: Per Kjellander Commit-Queue: Ilya Nikolaevskiy Reviewed-by: Ilya Nikolaevskiy - Reviewed-by: Per Kjellander - Cr-Commit-Position: refs/heads/main@{#39953} + Cr-Commit-Position: refs/heads/main@{#39983} -Differential Revision: https://phabricator.services.mozilla.com/D176507 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/dabb9e2ec9d3b77e4cc19de0fb98cae4ce88293d +Differential Revision: https://phabricator.services.mozilla.com/D177237 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/854cc79e99130e6537eebe8433a6a7adf5e1578d --- - .../test/video_capture_unittest.cc | 33 +++++++++++++++++++ - .../video_capture/windows/video_capture_ds.cc | 18 +++++----- - 2 files changed, 41 insertions(+), 10 deletions(-) + modules/video_capture/windows/device_info_ds.cc | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) -diff --git a/modules/video_capture/test/video_capture_unittest.cc b/modules/video_capture/test/video_capture_unittest.cc -index 4cf3d5931c..c8af222b57 100644 ---- a/modules/video_capture/test/video_capture_unittest.cc -+++ b/modules/video_capture/test/video_capture_unittest.cc -@@ -341,3 +341,36 @@ TEST_F(VideoCaptureTest, DISABLED_TestTwoCameras) { - EXPECT_EQ(0, module2->StopCapture()); - EXPECT_EQ(0, module1->StopCapture()); - } -+ -+#ifdef WEBRTC_MAC -+// No VideoCaptureImpl on Mac. -+#define MAYBE_ConcurrentAccess DISABLED_ConcurrentAccess -+#else -+#define MAYBE_ConcurrentAccess ConcurrentAccess -+#endif -+TEST_F(VideoCaptureTest, MAYBE_ConcurrentAccess) { -+ TestVideoCaptureCallback capture_observer1; -+ rtc::scoped_refptr module1( -+ OpenVideoCaptureDevice(0, &capture_observer1)); -+ ASSERT_TRUE(module1.get() != NULL); -+ VideoCaptureCapability capability; -+ device_info_->GetCapability(module1->CurrentDeviceName(), 0, capability); -+ capture_observer1.SetExpectedCapability(capability); -+ -+ TestVideoCaptureCallback capture_observer2; -+ rtc::scoped_refptr module2( -+ OpenVideoCaptureDevice(0, &capture_observer2)); -+ ASSERT_TRUE(module2.get() != NULL); -+ capture_observer2.SetExpectedCapability(capability); -+ -+ // Starting module1 should work. -+ ASSERT_NO_FATAL_FAILURE(StartCapture(module1.get(), capability)); -+ EXPECT_TRUE_WAIT(capture_observer1.incoming_frames() >= 5, kTimeOut); +diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc +index b5867923d1..f6927281f3 100644 +--- a/modules/video_capture/windows/device_info_ds.cc ++++ b/modules/video_capture/windows/device_info_ds.cc +@@ -519,11 +519,18 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) + hrVC = videoControlConfig->GetFrameRateList( + outputCapturePin, tmp, size, &listSize, &frameDurationList); + ++ if (hrVC == S_OK) { ++ maxFPS = GetMaxOfFrameArray(frameDurationList, listSize); ++ } + -+ // When module1 is stopped, starting module2 for the same device should work. -+ EXPECT_EQ(0, module1->StopCapture()); -+ ASSERT_NO_FATAL_FAILURE(StartCapture(module2.get(), capability)); -+ EXPECT_TRUE_WAIT(capture_observer2.incoming_frames() >= 5, kTimeOut); ++ CoTaskMemFree(frameDurationList); ++ frameDurationList = NULL; ++ listSize = 0; + -+ EXPECT_EQ(0, module2->StopCapture()); -+} -diff --git a/modules/video_capture/windows/video_capture_ds.cc b/modules/video_capture/windows/video_capture_ds.cc -index 74b31d98be..8695f76245 100644 ---- a/modules/video_capture/windows/video_capture_ds.cc -+++ b/modules/video_capture/windows/video_capture_ds.cc -@@ -113,17 +113,9 @@ int32_t VideoCaptureDS::Init(const char* deviceUniqueIdUTF8) { - return -1; - } - -- // Temporary connect here. -- // This is done so that no one else can use the capture device. - if (SetCameraOutput(_requestedCapability) != 0) { - return -1; - } -- hr = _mediaControl->Pause(); -- if (FAILED(hr)) { -- RTC_LOG(LS_INFO) -- << "Failed to Pause the Capture device. Is it already occupied? " << hr; -- return -1; -- } - RTC_LOG(LS_INFO) << "Capture device '" << deviceUniqueIdUTF8 - << "' initialized."; - return 0; -@@ -139,7 +131,13 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { - return -1; - } - } -- HRESULT hr = _mediaControl->Run(); -+ HRESULT hr = _mediaControl->Pause(); -+ if (FAILED(hr)) { -+ RTC_LOG(LS_INFO) -+ << "Failed to Pause the Capture device. Is it already occupied? " << hr; -+ return -1; -+ } -+ hr = _mediaControl->Run(); - if (FAILED(hr)) { - RTC_LOG(LS_INFO) << "Failed to start the Capture device."; - return -1; -@@ -150,7 +148,7 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { - int32_t VideoCaptureDS::StopCapture() { - MutexLock lock(&api_lock_); - -- HRESULT hr = _mediaControl->Pause(); -+ HRESULT hr = _mediaControl->StopWhenReady(); - if (FAILED(hr)) { - RTC_LOG(LS_INFO) << "Failed to stop the capture graph. " << hr; - return -1; + // On some odd cameras, you may get a 0 for duration. Some others may + // not update the out vars. GetMaxOfFrameArray returns the lowest + // duration (highest FPS), or 0 if there was no list with elements. +- if (hrVC == S_OK && +- 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, listSize))) { ++ if (0 != maxFPS) { + capability.maxFPS = static_cast(10000000 / maxFPS); + capability.supportFrameRateControl = true; + } else // use existing method -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0095.patch b/third_party/libwebrtc/moz-patch-stack/0095.patch index 95fe9665c6414..09b70568a9760 100644 --- a/third_party/libwebrtc/moz-patch-stack/0095.patch +++ b/third_party/libwebrtc/moz-patch-stack/0095.patch @@ -1,71 +1,54 @@ From: Andreas Pehrson -Date: Wed, 10 May 2023 08:01:00 +0000 -Subject: Bug 1828065 - cherry-pick upstream libwebrtc commit 6fc1ae58be. - r=webrtc-reviewers,mjf +Date: Wed, 10 May 2023 18:06:00 +0000 +Subject: Bug 1831824 - libwebrtc: In PacketSequencer set timestamps of rtx + padding packets when there is no last packet. r=webrtc-reviewers,dbaker -Upstream commit: https://webrtc.googlesource.com/src/+/6fc1ae58be7cbb61ad0431d90eb7a7dc333de2f2 - In DeviceInfoDS check that out vars were set +Prior to this patch timestamps are not adjusted when they are 0, and they are 0 +when the packet sequencer has not yet seen a media packet. Code and comments in +PacketSequencer and RTPSender::GeneratePadding make it clear that rtx padding +packets are allowed prior to seeing a media packet, and therefore the 0 +timestamp case has to be handled. - Bug: chromium:1441804 - Change-Id: Id07cb61519315d77c2d7cdab1053efaaf7473e1a - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304060 - Reviewed-by: Ilya Nikolaevskiy - Reviewed-by: Per Kjellander - Commit-Queue: Ilya Nikolaevskiy - Cr-Commit-Position: refs/heads/main@{#39982} +For rtx the padding packets do not need to have the same timestamp as any media +packets, like plain padding packets do -- because they can only be part of a media +frame, so a media packet has to be known. -Differential Revision: https://phabricator.services.mozilla.com/D177236 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/60d381b6016ae5af0181b44c6a31b41eab094793 +With this patch both rtp timestamps and capture timestamps are set to current +time when sequencing rtx padding packets without having seen a media packet. + +This fixes a DCHECK failure in TransmissionOffset::Write. + +Differential Revision: https://phabricator.services.mozilla.com/D177306 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b0339fd77c82c4c54e5aacaeef66d739b1643827 --- - modules/video_capture/windows/device_info_ds.cc | 13 +++++++------ - modules/video_capture/windows/help_functions_ds.cc | 3 +++ - 2 files changed, 10 insertions(+), 6 deletions(-) + modules/rtp_rtcp/source/packet_sequencer.cc | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) -diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index 6b4c57d01e..2c192fe4f6 100644 ---- a/modules/video_capture/windows/device_info_ds.cc -+++ b/modules/video_capture/windows/device_info_ds.cc -@@ -505,9 +505,9 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) - } +diff --git a/modules/rtp_rtcp/source/packet_sequencer.cc b/modules/rtp_rtcp/source/packet_sequencer.cc +index 55edd768a8..acc2e87aa3 100644 +--- a/modules/rtp_rtcp/source/packet_sequencer.cc ++++ b/modules/rtp_rtcp/source/packet_sequencer.cc +@@ -118,8 +118,18 @@ void PacketSequencer::PopulatePaddingFields(RtpPacketToSend& packet) { + return; + } - if (hrVC == S_OK) { -- LONGLONG* frameDurationList; -- LONGLONG maxFPS; -- long listSize; -+ LONGLONG* frameDurationList = NULL; -+ LONGLONG maxFPS = 0; -+ long listSize = 0; - SIZE size; - size.cx = capability.width; - size.cy = capability.height; -@@ -520,9 +520,10 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) - hrVC = videoControlConfig->GetFrameRateList( - outputCapturePin, tmp, size, &listSize, &frameDurationList); - -- // On some odd cameras, you may get a 0 for duration. -- // GetMaxOfFrameArray returns the lowest duration (highest FPS) -- if (hrVC == S_OK && listSize > 0 && -+ // On some odd cameras, you may get a 0 for duration. Some others may -+ // not update the out vars. GetMaxOfFrameArray returns the lowest -+ // duration (highest FPS), or 0 if there was no list with elements. -+ if (hrVC == S_OK && - 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, listSize))) { - capability.maxFPS = static_cast(10000000 / maxFPS); - capability.supportFrameRateControl = true; -diff --git a/modules/video_capture/windows/help_functions_ds.cc b/modules/video_capture/windows/help_functions_ds.cc -index b767726107..47fecfe4a1 100644 ---- a/modules/video_capture/windows/help_functions_ds.cc -+++ b/modules/video_capture/windows/help_functions_ds.cc -@@ -21,6 +21,9 @@ namespace webrtc { - namespace videocapturemodule { - // This returns minimum :), which will give max frame rate... - LONGLONG GetMaxOfFrameArray(LONGLONG* maxFps, long size) { -+ if (!maxFps || size <= 0) { -+ return 0; +- packet.SetTimestamp(last_rtp_timestamp_); +- packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); ++ if (last_timestamp_time_ms_ > 0) { ++ RTC_DCHECK_GT(last_rtp_timestamp_, 0); ++ RTC_DCHECK_GT(last_capture_time_ms_, 0); ++ packet.SetTimestamp(last_rtp_timestamp_); ++ packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); ++ } else { ++ // No media packet has been sent yet so timestamps are not known. Set them ++ // now as they will be needed when serializing the packet later on. ++ auto now = clock_->CurrentTime(); ++ packet.SetTimestamp(now.ms() * kTimestampTicksPerMs); ++ packet.set_capture_time(now); + } - LONGLONG maxFPS = maxFps[0]; - for (int i = 0; i < size; i++) { - if (maxFPS > maxFps[i]) + + // Only change the timestamp of padding packets sent over RTX. + // Padding only packets over RTP has to be sent as part of a media -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0096.patch b/third_party/libwebrtc/moz-patch-stack/0096.patch index 65b445cb91f7c..998658fa1cb84 100644 --- a/third_party/libwebrtc/moz-patch-stack/0096.patch +++ b/third_party/libwebrtc/moz-patch-stack/0096.patch @@ -1,52 +1,43 @@ From: Andreas Pehrson -Date: Wed, 10 May 2023 08:01:00 +0000 -Subject: Bug 1828065 - cherry-pick upstream libwebrtc commit adf55790b6. - r=webrtc-reviewers,mjf +Date: Tue, 16 May 2023 06:37:00 +0000 +Subject: Bug 1832770 - Cherry-pick upstream libwebrtc commit 7b0d7f48fb. + r=grulja,webrtc-reviewers,mjf -Upstream commit: https://webrtc.googlesource.com/src/+/adf55790b6ecf50c4bb2b2cf7d58441303b9d946 - In DeviceInfoDS free the frame duration list after use +Upstream commit: + PipeWire capturer: fix fcntl call when duplicating a file descriptor - Per the docs, the caller is responsible for freeing the memory. + The fcntl() call has variable arguments, therefore we need to pass 0 to + specify there are no other arguments for this call, otherwise we might + end up with an argument that is random garbage. - Bug: chromium:1441804 - Change-Id: I9aaae493a1a86d8ab4f03930715a643a3c9fb61b - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304061 - Reviewed-by: Per Kjellander - Commit-Queue: Ilya Nikolaevskiy - Reviewed-by: Ilya Nikolaevskiy - Cr-Commit-Position: refs/heads/main@{#39983} + Bug: webrtc:15174 + Change-Id: I34f16a942d80913b667d8ade7eed557b0233be01 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305120 + Reviewed-by: Alexander Cooper + Commit-Queue: Jan Grulich + Cr-Commit-Position: refs/heads/main@{#40060} -Differential Revision: https://phabricator.services.mozilla.com/D177237 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/854cc79e99130e6537eebe8433a6a7adf5e1578d +Differential Revision: https://phabricator.services.mozilla.com/D178009 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/47978aa145282f737fc77fcdcadc995e80e2a743 --- - modules/video_capture/windows/device_info_ds.cc | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) + .../desktop_capture/linux/wayland/shared_screencast_stream.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/modules/video_capture/windows/device_info_ds.cc b/modules/video_capture/windows/device_info_ds.cc -index 2c192fe4f6..2b01fc6930 100644 ---- a/modules/video_capture/windows/device_info_ds.cc -+++ b/modules/video_capture/windows/device_info_ds.cc -@@ -520,11 +520,18 @@ int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8) - hrVC = videoControlConfig->GetFrameRateList( - outputCapturePin, tmp, size, &listSize, &frameDurationList); +diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +index 1eea8bfbf5..17c895088a 100644 +--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc ++++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +@@ -449,8 +449,8 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( + PipeWireThreadLoopLock thread_loop_lock(pw_main_loop_); -+ if (hrVC == S_OK) { -+ maxFPS = GetMaxOfFrameArray(frameDurationList, listSize); -+ } -+ -+ CoTaskMemFree(frameDurationList); -+ frameDurationList = NULL; -+ listSize = 0; -+ - // On some odd cameras, you may get a 0 for duration. Some others may - // not update the out vars. GetMaxOfFrameArray returns the lowest - // duration (highest FPS), or 0 if there was no list with elements. -- if (hrVC == S_OK && -- 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, listSize))) { -+ if (0 != maxFPS) { - capability.maxFPS = static_cast(10000000 / maxFPS); - capability.supportFrameRateControl = true; - } else // use existing method + if (fd >= 0) { +- pw_core_ = pw_context_connect_fd(pw_context_, fcntl(fd, F_DUPFD_CLOEXEC), +- nullptr, 0); ++ pw_core_ = pw_context_connect_fd( ++ pw_context_, fcntl(fd, F_DUPFD_CLOEXEC, 0), nullptr, 0); + } else { + pw_core_ = pw_context_connect(pw_context_, nullptr, 0); + } -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0097.patch b/third_party/libwebrtc/moz-patch-stack/0097.patch index 09b70568a9760..0eabea9831093 100644 --- a/third_party/libwebrtc/moz-patch-stack/0097.patch +++ b/third_party/libwebrtc/moz-patch-stack/0097.patch @@ -1,51 +1,37 @@ From: Andreas Pehrson -Date: Wed, 10 May 2023 18:06:00 +0000 -Subject: Bug 1831824 - libwebrtc: In PacketSequencer set timestamps of rtx - padding packets when there is no last packet. r=webrtc-reviewers,dbaker +Date: Tue, 16 May 2023 06:38:00 +0000 +Subject: Bug 1832804 - Revert changeset b0339fd77c82. r=webrtc-reviewers,mjf -Prior to this patch timestamps are not adjusted when they are 0, and they are 0 -when the packet sequencer has not yet seen a media packet. Code and comments in -PacketSequencer and RTPSender::GeneratePadding make it clear that rtx padding -packets are allowed prior to seeing a media packet, and therefore the 0 -timestamp case has to be handled. +This bit is now restored to original libwebrtc M111 code. -For rtx the padding packets do not need to have the same timestamp as any media -packets, like plain padding packets do -- because they can only be part of a media -frame, so a media packet has to be known. - -With this patch both rtp timestamps and capture timestamps are set to current -time when sequencing rtx padding packets without having seen a media packet. - -This fixes a DCHECK failure in TransmissionOffset::Write. - -Differential Revision: https://phabricator.services.mozilla.com/D177306 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b0339fd77c82c4c54e5aacaeef66d739b1643827 +Differential Revision: https://phabricator.services.mozilla.com/D178006 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/47b1b27c8f75293c0861ca6197d438076ca9e693 --- - modules/rtp_rtcp/source/packet_sequencer.cc | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) + modules/rtp_rtcp/source/packet_sequencer.cc | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/modules/rtp_rtcp/source/packet_sequencer.cc b/modules/rtp_rtcp/source/packet_sequencer.cc -index 55edd768a8..acc2e87aa3 100644 +index acc2e87aa3..55edd768a8 100644 --- a/modules/rtp_rtcp/source/packet_sequencer.cc +++ b/modules/rtp_rtcp/source/packet_sequencer.cc -@@ -118,8 +118,18 @@ void PacketSequencer::PopulatePaddingFields(RtpPacketToSend& packet) { +@@ -118,18 +118,8 @@ void PacketSequencer::PopulatePaddingFields(RtpPacketToSend& packet) { return; } -- packet.SetTimestamp(last_rtp_timestamp_); -- packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); -+ if (last_timestamp_time_ms_ > 0) { -+ RTC_DCHECK_GT(last_rtp_timestamp_, 0); -+ RTC_DCHECK_GT(last_capture_time_ms_, 0); -+ packet.SetTimestamp(last_rtp_timestamp_); -+ packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); -+ } else { -+ // No media packet has been sent yet so timestamps are not known. Set them -+ // now as they will be needed when serializing the packet later on. -+ auto now = clock_->CurrentTime(); -+ packet.SetTimestamp(now.ms() * kTimestampTicksPerMs); -+ packet.set_capture_time(now); -+ } +- if (last_timestamp_time_ms_ > 0) { +- RTC_DCHECK_GT(last_rtp_timestamp_, 0); +- RTC_DCHECK_GT(last_capture_time_ms_, 0); +- packet.SetTimestamp(last_rtp_timestamp_); +- packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); +- } else { +- // No media packet has been sent yet so timestamps are not known. Set them +- // now as they will be needed when serializing the packet later on. +- auto now = clock_->CurrentTime(); +- packet.SetTimestamp(now.ms() * kTimestampTicksPerMs); +- packet.set_capture_time(now); +- } ++ packet.SetTimestamp(last_rtp_timestamp_); ++ packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); // Only change the timestamp of padding packets sent over RTX. // Padding only packets over RTP has to be sent as part of a media diff --git a/third_party/libwebrtc/moz-patch-stack/0098.patch b/third_party/libwebrtc/moz-patch-stack/0098.patch index 310d45463bd60..aa37a5ba58578 100644 --- a/third_party/libwebrtc/moz-patch-stack/0098.patch +++ b/third_party/libwebrtc/moz-patch-stack/0098.patch @@ -1,41 +1,81 @@ From: Andreas Pehrson -Date: Tue, 16 May 2023 06:37:00 +0000 -Subject: Bug 1832770 - Cherry-pick upstream libwebrtc commit 7b0d7f48fb. - r=grulja,webrtc-reviewers,mjf +Date: Tue, 16 May 2023 06:38:00 +0000 +Subject: Bug 1832804 - cherry-pick upstream webrtc commit a09331a603. + r=webrtc-reviewers,mjf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit -Upstream commit: - PipeWire capturer: fix fcntl call when duplicating a file descriptor +Upstream commit: https://webrtc.googlesource.com/src/+/a09331a6038bb6191c7662680d8928940463a099 + Don't write TransmissionOffset when capture time is not set - The fcntl() call has variable arguments, therefore we need to pass 0 to - specify there are no other arguments for this call, otherwise we might - end up with an argument that is random garbage. + RTX padding packets sent before media packets can legitimately have no + timestamps set (they are 0). Writing the TransmissionOffset extension + with capture time 0 will overflow once current time exceeds ~3 minutes. - Bug: webrtc:15174 - Change-Id: I34f16a942d80913b667d8ade7eed557b0233be01 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305120 - Reviewed-by: Alexander Cooper - Commit-Queue: Jan Grulich - Cr-Commit-Position: refs/heads/main@{#40060} + Bug: webrtc:15172 + Change-Id: I4dd1f341802d45016549b330f0e08cd3a00cfa19 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305020 + Reviewed-by: Erik SprÃ¥ng + Reviewed-by: Per Kjellander + Commit-Queue: Danil Chapovalov + Reviewed-by: Danil Chapovalov + Cr-Commit-Position: refs/heads/main@{#40055} -Differential Revision: https://phabricator.services.mozilla.com/D178009 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/47978aa145282f737fc77fcdcadc995e80e2a743 +Differential Revision: https://phabricator.services.mozilla.com/D178007 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c303f3d267415184f3d023b022e4bd309d540fec --- - .../desktop_capture/linux/wayland/shared_screencast_stream.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + modules/rtp_rtcp/source/rtp_sender_egress.cc | 5 +++-- + .../source/rtp_sender_egress_unittest.cc | 20 +++++++++++++++++++ + 2 files changed, 23 insertions(+), 2 deletions(-) -diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc -index 21863b7d8d..17c895088a 100644 ---- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc -+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc -@@ -450,7 +450,7 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( +diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.cc b/modules/rtp_rtcp/source/rtp_sender_egress.cc +index 88f5d28c78..a9fa071379 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_egress.cc ++++ b/modules/rtp_rtcp/source/rtp_sender_egress.cc +@@ -209,8 +209,9 @@ void RtpSenderEgress::SendPacket(RtpPacketToSend* packet, + // In case of VideoTimingExtension, since it's present not in every packet, + // data after rtp header may be corrupted if these packets are protected by + // the FEC. +- TimeDelta diff = now - packet->capture_time(); +- if (packet->HasExtension()) { ++ if (packet->HasExtension() && ++ packet->capture_time() > Timestamp::Zero()) { ++ TimeDelta diff = now - packet->capture_time(); + packet->SetExtension(kTimestampTicksPerMs * diff.ms()); + } + if (packet->HasExtension()) { +diff --git a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc +index cc1c8feb8d..bfaffa1bdb 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc ++++ b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc +@@ -268,6 +268,26 @@ TEST_F(RtpSenderEgressTest, + EXPECT_TRUE(transport_.last_packet()->options.included_in_allocation); + } - if (fd >= 0) { - pw_core_ = pw_context_connect_fd( -- pw_context_, fcntl(fd, F_DUPFD_CLOEXEC), nullptr, 0); -+ pw_context_, fcntl(fd, F_DUPFD_CLOEXEC, 0), nullptr, 0); - } else { - pw_core_ = pw_context_connect(pw_context_, nullptr, 0); - } ++TEST_F(RtpSenderEgressTest, ++ DoesntWriteTransmissionOffsetOnRtxPaddingBeforeMedia) { ++ header_extensions_.RegisterByUri(kTransmissionOffsetExtensionId, ++ TransmissionOffset::Uri()); ++ ++ // Prior to sending media, timestamps are 0. ++ std::unique_ptr padding = ++ BuildRtpPacket(/*marker_bit=*/true, /*capture_time_ms=*/0); ++ padding->set_packet_type(RtpPacketMediaType::kPadding); ++ padding->SetSsrc(kRtxSsrc); ++ EXPECT_TRUE(padding->HasExtension()); ++ ++ std::unique_ptr sender = CreateRtpSenderEgress(); ++ sender->SendPacket(std::move(padding), PacedPacketInfo()); ++ ++ absl::optional offset = ++ transport_.last_packet()->packet.GetExtension(); ++ EXPECT_EQ(offset, 0); ++} ++ + TEST_F(RtpSenderEgressTest, OnSendSideDelayUpdated) { + StrictMock send_side_delay_observer; + RtpRtcpInterface::Configuration config = DefaultConfig(); -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0099.patch b/third_party/libwebrtc/moz-patch-stack/0099.patch index 0eabea9831093..263f9c50b9276 100644 --- a/third_party/libwebrtc/moz-patch-stack/0099.patch +++ b/third_party/libwebrtc/moz-patch-stack/0099.patch @@ -1,40 +1,38 @@ From: Andreas Pehrson -Date: Tue, 16 May 2023 06:38:00 +0000 -Subject: Bug 1832804 - Revert changeset b0339fd77c82. r=webrtc-reviewers,mjf +Date: Wed, 17 May 2023 08:25:00 +0000 +Subject: Bug 1830945 - Do not lock in VideoCaptureDS::{Start|Stop}Capture. + r=padenot -This bit is now restored to original libwebrtc M111 code. +Unclear what they are guarding. -Differential Revision: https://phabricator.services.mozilla.com/D178006 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/47b1b27c8f75293c0861ca6197d438076ca9e693 +Differential Revision: https://phabricator.services.mozilla.com/D178279 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fcd48e81c9c2cb68ea2cb3d44b3574281be2154e --- - modules/rtp_rtcp/source/packet_sequencer.cc | 14 ++------------ - 1 file changed, 2 insertions(+), 12 deletions(-) + modules/video_capture/windows/video_capture_ds.cc | 4 ---- + 1 file changed, 4 deletions(-) -diff --git a/modules/rtp_rtcp/source/packet_sequencer.cc b/modules/rtp_rtcp/source/packet_sequencer.cc -index acc2e87aa3..55edd768a8 100644 ---- a/modules/rtp_rtcp/source/packet_sequencer.cc -+++ b/modules/rtp_rtcp/source/packet_sequencer.cc -@@ -118,18 +118,8 @@ void PacketSequencer::PopulatePaddingFields(RtpPacketToSend& packet) { - return; - } +diff --git a/modules/video_capture/windows/video_capture_ds.cc b/modules/video_capture/windows/video_capture_ds.cc +index 8695f76245..b13ac074f8 100644 +--- a/modules/video_capture/windows/video_capture_ds.cc ++++ b/modules/video_capture/windows/video_capture_ds.cc +@@ -122,8 +122,6 @@ int32_t VideoCaptureDS::Init(const char* deviceUniqueIdUTF8) { + } -- if (last_timestamp_time_ms_ > 0) { -- RTC_DCHECK_GT(last_rtp_timestamp_, 0); -- RTC_DCHECK_GT(last_capture_time_ms_, 0); -- packet.SetTimestamp(last_rtp_timestamp_); -- packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); -- } else { -- // No media packet has been sent yet so timestamps are not known. Set them -- // now as they will be needed when serializing the packet later on. -- auto now = clock_->CurrentTime(); -- packet.SetTimestamp(now.ms() * kTimestampTicksPerMs); -- packet.set_capture_time(now); -- } -+ packet.SetTimestamp(last_rtp_timestamp_); -+ packet.set_capture_time(Timestamp::Millis(last_capture_time_ms_)); + int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { +- MutexLock lock(&api_lock_); +- + if (capability != _requestedCapability) { + DisconnectGraph(); - // Only change the timestamp of padding packets sent over RTX. - // Padding only packets over RTP has to be sent as part of a media +@@ -146,8 +144,6 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { + } + + int32_t VideoCaptureDS::StopCapture() { +- MutexLock lock(&api_lock_); +- + HRESULT hr = _mediaControl->StopWhenReady(); + if (FAILED(hr)) { + RTC_LOG(LS_INFO) << "Failed to stop the capture graph. " << hr; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0100.patch b/third_party/libwebrtc/moz-patch-stack/0100.patch index ccaff7261b75b..4f2b31301a854 100644 --- a/third_party/libwebrtc/moz-patch-stack/0100.patch +++ b/third_party/libwebrtc/moz-patch-stack/0100.patch @@ -1,81 +1,789 @@ From: Andreas Pehrson -Date: Tue, 16 May 2023 06:38:00 +0000 -Subject: Bug 1832804 - cherry-pick upstream webrtc commit a09331a603. - r=webrtc-reviewers,mjf -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit +Date: Wed, 17 May 2023 13:30:00 +0000 +Subject: Bug 1833101 - From libwebrtc, remove + desktop_capture/screen_capturer_mac.mm. r=mjf,webrtc-reviewers -Upstream commit: https://webrtc.googlesource.com/src/+/a09331a6038bb6191c7662680d8928940463a099 - Don't write TransmissionOffset when capture time is not set +This is code existing only in our local copy. - RTX padding packets sent before media packets can legitimately have no - timestamps set (they are 0). Writing the TransmissionOffset extension - with capture time 0 will overflow once current time exceeds ~3 minutes. - - Bug: webrtc:15172 - Change-Id: I4dd1f341802d45016549b330f0e08cd3a00cfa19 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/305020 - Reviewed-by: Erik SprÃ¥ng - Reviewed-by: Per Kjellander - Commit-Queue: Danil Chapovalov - Reviewed-by: Danil Chapovalov - Cr-Commit-Position: refs/heads/main@{#40055} - -Differential Revision: https://phabricator.services.mozilla.com/D178007 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c303f3d267415184f3d023b022e4bd309d540fec +Differential Revision: https://phabricator.services.mozilla.com/D178026 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/92458cfcd52ce53b2f25ba9604fe70ef7f8054d4 --- - modules/rtp_rtcp/source/rtp_sender_egress.cc | 5 +++-- - .../source/rtp_sender_egress_unittest.cc | 20 +++++++++++++++++++ - 2 files changed, 23 insertions(+), 2 deletions(-) + .../desktop_capture/screen_capturer_mac.mm | 766 ------------------ + 1 file changed, 766 deletions(-) + delete mode 100644 modules/desktop_capture/screen_capturer_mac.mm -diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.cc b/modules/rtp_rtcp/source/rtp_sender_egress.cc -index d8163dc2e7..7931dd824d 100644 ---- a/modules/rtp_rtcp/source/rtp_sender_egress.cc -+++ b/modules/rtp_rtcp/source/rtp_sender_egress.cc -@@ -210,8 +210,9 @@ void RtpSenderEgress::SendPacket(RtpPacketToSend* packet, - // In case of VideoTimingExtension, since it's present not in every packet, - // data after rtp header may be corrupted if these packets are protected by - // the FEC. -- TimeDelta diff = now - packet->capture_time(); -- if (packet->HasExtension()) { -+ if (packet->HasExtension() && -+ packet->capture_time() > Timestamp::Zero()) { -+ TimeDelta diff = now - packet->capture_time(); - packet->SetExtension(kTimestampTicksPerMs * diff.ms()); - } - if (packet->HasExtension()) { -diff --git a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc -index cc1c8feb8d..bfaffa1bdb 100644 ---- a/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc -+++ b/modules/rtp_rtcp/source/rtp_sender_egress_unittest.cc -@@ -268,6 +268,26 @@ TEST_F(RtpSenderEgressTest, - EXPECT_TRUE(transport_.last_packet()->options.included_in_allocation); - } - -+TEST_F(RtpSenderEgressTest, -+ DoesntWriteTransmissionOffsetOnRtxPaddingBeforeMedia) { -+ header_extensions_.RegisterByUri(kTransmissionOffsetExtensionId, -+ TransmissionOffset::Uri()); -+ -+ // Prior to sending media, timestamps are 0. -+ std::unique_ptr padding = -+ BuildRtpPacket(/*marker_bit=*/true, /*capture_time_ms=*/0); -+ padding->set_packet_type(RtpPacketMediaType::kPadding); -+ padding->SetSsrc(kRtxSsrc); -+ EXPECT_TRUE(padding->HasExtension()); -+ -+ std::unique_ptr sender = CreateRtpSenderEgress(); -+ sender->SendPacket(std::move(padding), PacedPacketInfo()); -+ -+ absl::optional offset = -+ transport_.last_packet()->packet.GetExtension(); -+ EXPECT_EQ(offset, 0); -+} -+ - TEST_F(RtpSenderEgressTest, OnSendSideDelayUpdated) { - StrictMock send_side_delay_observer; - RtpRtcpInterface::Configuration config = DefaultConfig(); +diff --git a/modules/desktop_capture/screen_capturer_mac.mm b/modules/desktop_capture/screen_capturer_mac.mm +deleted file mode 100644 +index 285086ffa6..0000000000 +--- a/modules/desktop_capture/screen_capturer_mac.mm ++++ /dev/null +@@ -1,766 +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 +- +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include "modules/desktop_capture/desktop_capture_options.h" +-#include "modules/desktop_capture/desktop_capturer.h" +-#include "modules/desktop_capture/desktop_frame.h" +-#include "modules/desktop_capture/desktop_geometry.h" +-#include "modules/desktop_capture/desktop_region.h" +-#include "modules/desktop_capture/mac/desktop_configuration.h" +-#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" +-#include "modules/desktop_capture/mac/scoped_pixel_buffer_object.h" +-#include "modules/desktop_capture/screen_capture_frame_queue.h" +-#include "modules/desktop_capture/screen_capturer_helper.h" +-#include "modules/desktop_capture/shared_desktop_frame.h" +-#include "rtc_base/checks.h" +-#include "rtc_base/constructormagic.h" +-#include "rtc_base/logging.h" +-#include "rtc_base/macutils.h" +-#include "rtc_base/timeutils.h" +- +-namespace webrtc { +- +-namespace { +- +-// CGDisplayStreamRefs need to be destroyed asynchronously after receiving a +-// kCGDisplayStreamFrameStatusStopped callback from CoreGraphics. This may +-// happen after the ScreenCapturerMac has been destroyed. DisplayStreamManager +-// is responsible for destroying all extant CGDisplayStreamRefs, and will +-// destroy itself once it's done. +-class DisplayStreamManager { +- public: +- int GetUniqueId() { return ++unique_id_generator_; } +- void DestroyStream(int unique_id) { +- auto it = display_stream_wrappers_.find(unique_id); +- RTC_CHECK(it != display_stream_wrappers_.end()); +- RTC_CHECK(!it->second.active); +- CFRelease(it->second.stream); +- display_stream_wrappers_.erase(it); +- +- if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) +- delete this; +- } +- +- void SaveStream(int unique_id, +- CGDisplayStreamRef stream) { +- RTC_CHECK(unique_id <= unique_id_generator_); +- DisplayStreamWrapper wrapper; +- wrapper.stream = stream; +- display_stream_wrappers_[unique_id] = wrapper; +- } +- +- void UnregisterActiveStreams() { +- for (auto& pair : display_stream_wrappers_) { +- DisplayStreamWrapper& wrapper = pair.second; +- if (wrapper.active) { +- wrapper.active = false; +- CFRunLoopSourceRef source = +- CGDisplayStreamGetRunLoopSource(wrapper.stream); +- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, +- kCFRunLoopCommonModes); +- CGDisplayStreamStop(wrapper.stream); +- } +- } +- } +- +- void PrepareForSelfDestruction() { +- ready_for_self_destruction_ = true; +- +- if (display_stream_wrappers_.empty()) +- delete this; +- } +- +- // Once the DisplayStreamManager is ready for destruction, the +- // ScreenCapturerMac is no longer present. Any updates should be ignored. +- bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; } +- +- private: +- struct DisplayStreamWrapper { +- // The registered CGDisplayStreamRef. +- CGDisplayStreamRef stream = nullptr; +- +- // Set to false when the stream has been stopped. An asynchronous callback +- // from CoreGraphics will let us destroy the CGDisplayStreamRef. +- bool active = true; +- }; +- +- std::map display_stream_wrappers_; +- int unique_id_generator_ = 0; +- bool ready_for_self_destruction_ = false; +-}; +- +-// Standard Mac displays have 72dpi, but we report 96dpi for +-// consistency with Windows and Linux. +-const int kStandardDPI = 96; +- +-// Scales all coordinates of a rect by a specified factor. +-DesktopRect ScaleAndRoundCGRect(const CGRect& rect, float scale) { +- return DesktopRect::MakeLTRB( +- static_cast(floor(rect.origin.x * scale)), +- static_cast(floor(rect.origin.y * scale)), +- static_cast(ceil((rect.origin.x + rect.size.width) * scale)), +- static_cast(ceil((rect.origin.y + rect.size.height) * scale))); +-} +- +-// Copy pixels in the |rect| from |src_place| to |dest_plane|. |rect| should be +-// relative to the origin of |src_plane| and |dest_plane|. +-void CopyRect(const uint8_t* src_plane, +- int src_plane_stride, +- uint8_t* dest_plane, +- int dest_plane_stride, +- int bytes_per_pixel, +- const DesktopRect& rect) { +- // Get the address of the starting point. +- const int src_y_offset = src_plane_stride * rect.top(); +- const int dest_y_offset = dest_plane_stride * rect.top(); +- const int x_offset = bytes_per_pixel * rect.left(); +- src_plane += src_y_offset + x_offset; +- dest_plane += dest_y_offset + x_offset; +- +- // Copy pixels in the rectangle line by line. +- const int bytes_per_line = bytes_per_pixel * rect.width(); +- const int height = rect.height(); +- for (int i = 0 ; i < height; ++i) { +- memcpy(dest_plane, src_plane, bytes_per_line); +- src_plane += src_plane_stride; +- dest_plane += dest_plane_stride; +- } +-} +- +-// Returns an array of CGWindowID for all the on-screen windows except +-// |window_to_exclude|, or NULL if the window is not found or it fails. The +-// caller should release the returned CFArrayRef. +-CFArrayRef CreateWindowListWithExclusion(CGWindowID window_to_exclude) { +- if (!window_to_exclude) +- return nullptr; +- +- CFArrayRef all_windows = CGWindowListCopyWindowInfo( +- kCGWindowListOptionOnScreenOnly, kCGNullWindowID); +- if (!all_windows) +- return nullptr; +- +- CFMutableArrayRef returned_array = +- CFArrayCreateMutable(nullptr, CFArrayGetCount(all_windows), nullptr); +- +- bool found = false; +- for (CFIndex i = 0; i < CFArrayGetCount(all_windows); ++i) { +- CFDictionaryRef window = reinterpret_cast( +- CFArrayGetValueAtIndex(all_windows, i)); +- +- CFNumberRef id_ref = reinterpret_cast( +- CFDictionaryGetValue(window, kCGWindowNumber)); +- +- CGWindowID id; +- CFNumberGetValue(id_ref, kCFNumberIntType, &id); +- if (id == window_to_exclude) { +- found = true; +- continue; +- } +- CFArrayAppendValue(returned_array, reinterpret_cast(id)); +- } +- CFRelease(all_windows); +- +- if (!found) { +- CFRelease(returned_array); +- returned_array = nullptr; +- } +- return returned_array; +-} +- +-// Returns the bounds of |window| in physical pixels, enlarged by a small amount +-// on four edges to take account of the border/shadow effects. +-DesktopRect GetExcludedWindowPixelBounds(CGWindowID window, +- float dip_to_pixel_scale) { +- // The amount of pixels to add to the actual window bounds to take into +- // account of the border/shadow effects. +- static const int kBorderEffectSize = 20; +- CGRect rect; +- CGWindowID ids[1]; +- ids[0] = window; +- +- CFArrayRef window_id_array = +- CFArrayCreate(nullptr, reinterpret_cast(&ids), 1, nullptr); +- CFArrayRef window_array = +- CGWindowListCreateDescriptionFromArray(window_id_array); +- +- if (CFArrayGetCount(window_array) > 0) { +- CFDictionaryRef window = reinterpret_cast( +- CFArrayGetValueAtIndex(window_array, 0)); +- CFDictionaryRef bounds_ref = reinterpret_cast( +- CFDictionaryGetValue(window, kCGWindowBounds)); +- CGRectMakeWithDictionaryRepresentation(bounds_ref, &rect); +- } +- +- CFRelease(window_id_array); +- CFRelease(window_array); +- +- rect.origin.x -= kBorderEffectSize; +- rect.origin.y -= kBorderEffectSize; +- rect.size.width += kBorderEffectSize * 2; +- rect.size.height += kBorderEffectSize * 2; +- // |rect| is in DIP, so convert to physical pixels. +- return ScaleAndRoundCGRect(rect, dip_to_pixel_scale); +-} +- +-// Create an image of the given region using the given |window_list|. +-// |pixel_bounds| should be in the primary display's coordinate in physical +-// pixels. The caller should release the returned CGImageRef and CFDataRef. +-CGImageRef CreateExcludedWindowRegionImage(const DesktopRect& pixel_bounds, +- float dip_to_pixel_scale, +- CFArrayRef window_list) { +- CGRect window_bounds; +- // The origin is in DIP while the size is in physical pixels. That's what +- // CGWindowListCreateImageFromArray expects. +- window_bounds.origin.x = pixel_bounds.left() / dip_to_pixel_scale; +- window_bounds.origin.y = pixel_bounds.top() / dip_to_pixel_scale; +- window_bounds.size.width = pixel_bounds.width(); +- window_bounds.size.height = pixel_bounds.height(); +- +- return CGWindowListCreateImageFromArray( +- window_bounds, window_list, kCGWindowImageDefault); +-} +- +-// A class to perform video frame capturing for mac. +-class ScreenCapturerMac : public DesktopCapturer { +- public: +- explicit ScreenCapturerMac( +- rtc::scoped_refptr desktop_config_monitor, +- bool detect_updated_region); +- ~ScreenCapturerMac() override; +- +- bool Init(); +- +- // DesktopCapturer interface. +- void Start(Callback* callback) override; +- void CaptureFrame() override; +- void SetExcludedWindow(WindowId window) override; +- bool GetSourceList(SourceList* screens) override; +- bool SelectSource(SourceId id) override; +- +- private: +- // Returns false if the selected screen is no longer valid. +- bool CgBlit(const DesktopFrame& frame, const DesktopRegion& region); +- +- // Called when the screen configuration is changed. +- void ScreenConfigurationChanged(); +- +- bool RegisterRefreshAndMoveHandlers(); +- void UnregisterRefreshAndMoveHandlers(); +- +- void ScreenRefresh(CGRectCount count, +- const CGRect *rect_array, +- DesktopVector display_origin); +- void ReleaseBuffers(); +- +- std::unique_ptr CreateFrame(); +- +- const bool detect_updated_region_; +- +- Callback* callback_ = nullptr; +- +- ScopedPixelBufferObject pixel_buffer_object_; +- +- // Queue of the frames buffers. +- ScreenCaptureFrameQueue queue_; +- +- // Current display configuration. +- MacDesktopConfiguration desktop_config_; +- +- // Currently selected display, or 0 if the full desktop is selected. On OS X +- // 10.6 and before, this is always 0. +- CGDirectDisplayID current_display_ = 0; +- +- // The physical pixel bounds of the current screen. +- DesktopRect screen_pixel_bounds_; +- +- // The dip to physical pixel scale of the current screen. +- float dip_to_pixel_scale_ = 1.0f; +- +- // A thread-safe list of invalid rectangles, and the size of the most +- // recently captured screen. +- ScreenCapturerHelper helper_; +- +- // Contains an invalid region from the previous capture. +- DesktopRegion last_invalid_region_; +- +- // Monitoring display reconfiguration. +- rtc::scoped_refptr desktop_config_monitor_; +- +- CGWindowID excluded_window_ = 0; +- +- // A self-owned object that will destroy itself after ScreenCapturerMac and +- // all display streams have been destroyed.. +- DisplayStreamManager* display_stream_manager_; +- +- // Used to force CaptureFrame to update it's screen configuration +- // and reregister event handlers. This ensure that this +- // occurs on the ScreenCapture thread. Read and written from +- // both the VideoCapture thread and ScreenCapture thread. +- // Protected by desktop_config_monitor_. +- bool update_screen_configuration_ = false; +- +- RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); +-}; +- +-// DesktopFrame wrapper that flips wrapped frame upside down by inverting +-// stride. +-class InvertedDesktopFrame : public DesktopFrame { +- public: +- InvertedDesktopFrame(std::unique_ptr frame) +- : DesktopFrame( +- frame->size(), +- -frame->stride(), +- frame->data() + (frame->size().height() - 1) * frame->stride(), +- frame->shared_memory()) { +- original_frame_ = std::move(frame); +- MoveFrameInfoFrom(original_frame_.get()); +- } +- ~InvertedDesktopFrame() override {} +- +- private: +- std::unique_ptr original_frame_; +- +- RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); +-}; +- +-ScreenCapturerMac::ScreenCapturerMac( +- rtc::scoped_refptr desktop_config_monitor, +- bool detect_updated_region) +- : detect_updated_region_(detect_updated_region), +- desktop_config_monitor_(desktop_config_monitor) { +- display_stream_manager_ = new DisplayStreamManager; +-} +- +-ScreenCapturerMac::~ScreenCapturerMac() { +- ReleaseBuffers(); +- UnregisterRefreshAndMoveHandlers(); +- display_stream_manager_->PrepareForSelfDestruction(); +-} +- +-bool ScreenCapturerMac::Init() { +- desktop_config_monitor_->Lock(); +- desktop_config_ = desktop_config_monitor_->desktop_configuration(); +- desktop_config_monitor_->Unlock(); +- if (!RegisterRefreshAndMoveHandlers()) { +- return false; +- } +- ScreenConfigurationChanged(); +- return true; +-} +- +-void ScreenCapturerMac::ReleaseBuffers() { +- // The buffers might be in use by the encoder, so don't delete them here. +- // Instead, mark them as "needs update"; next time the buffers are used by +- // the capturer, they will be recreated if necessary. +- queue_.Reset(); +-} +- +-void ScreenCapturerMac::Start(Callback* callback) { +- assert(!callback_); +- assert(callback); +- +- callback_ = callback; +- desktop_config_monitor_->Lock(); +- update_screen_configuration_ = true; +- desktop_config_monitor_->Unlock(); +-} +- +-void ScreenCapturerMac::CaptureFrame() { +- int64_t capture_start_time_nanos = rtc::TimeNanos(); +- +- // Spin RunLoop for 1/100th of a second, handling at most one source +- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true); +- +- queue_.MoveToNextFrame(); +- RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared()); +- +- desktop_config_monitor_->Lock(); +- MacDesktopConfiguration new_config = +- desktop_config_monitor_->desktop_configuration(); +- if (update_screen_configuration_ || !desktop_config_.Equals(new_config)) { +- update_screen_configuration_ = false; +- desktop_config_ = new_config; +- // If the display configuraiton has changed then refresh capturer data +- // structures. Occasionally, the refresh and move handlers are lost when +- // the screen mode changes, so re-register them here. +- UnregisterRefreshAndMoveHandlers(); +- RegisterRefreshAndMoveHandlers(); +- ScreenConfigurationChanged(); +- } +- +- DesktopRegion region; +- helper_.TakeInvalidRegion(®ion); +- +- // If the current buffer is from an older generation then allocate a new one. +- // Note that we can't reallocate other buffers at this point, since the caller +- // may still be reading from them. +- if (!queue_.current_frame()) +- queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(CreateFrame())); +- +- DesktopFrame* current_frame = queue_.current_frame(); +- +- if (!CgBlit(*current_frame, region)) { +- desktop_config_monitor_->Unlock(); +- callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); +- return; +- } +- std::unique_ptr new_frame = queue_.current_frame()->Share(); +- if (detect_updated_region_) { +- *new_frame->mutable_updated_region() = region; +- } else { +- new_frame->mutable_updated_region()->AddRect( +- DesktopRect::MakeSize(new_frame->size())); +- } +- +- if (current_display_) { +- const MacDisplayConfiguration* config = +- desktop_config_.FindDisplayConfigurationById(current_display_); +- if (config) { +- new_frame->set_top_left(config->bounds.top_left().subtract( +- desktop_config_.bounds.top_left())); +- } +- } +- +- helper_.set_size_most_recent(new_frame->size()); +- +- // Signal that we are done capturing data from the display framebuffer, +- // and accessing display structures. +- desktop_config_monitor_->Unlock(); +- +- new_frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / +- rtc::kNumNanosecsPerMillisec); +- callback_->OnCaptureResult(Result::SUCCESS, std::move(new_frame)); +-} +- +-void ScreenCapturerMac::SetExcludedWindow(WindowId window) { +- excluded_window_ = window; +-} +- +-bool ScreenCapturerMac::GetSourceList(SourceList* screens) { +- assert(screens->size() == 0); +- +- for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin(); +- it != desktop_config_.displays.end(); ++it) { +- screens->push_back({it->id}); +- } +- return true; +-} +- +-bool ScreenCapturerMac::SelectSource(SourceId id) { +- if (id == kFullDesktopScreenId) { +- current_display_ = 0; +- } else { +- const MacDisplayConfiguration* config = +- desktop_config_.FindDisplayConfigurationById( +- static_cast(id)); +- if (!config) +- return false; +- current_display_ = config->id; +- } +- +- ScreenConfigurationChanged(); +- return true; +-} +- +-bool ScreenCapturerMac::CgBlit(const DesktopFrame& frame, const DesktopRegion& region) { +- // Copy the entire contents of the previous capture buffer, to capture over. +- // TODO(wez): Get rid of this as per crbug.com/145064, or implement +- // crbug.com/92354. +- if (queue_.previous_frame()) { +- memcpy(frame.data(), queue_.previous_frame()->data(), +- frame.stride() * frame.size().height()); +- } +- +- MacDisplayConfigurations displays_to_capture; +- if (current_display_) { +- // Capturing a single screen. Note that the screen id may change when +- // screens are added or removed. +- const MacDisplayConfiguration* config = +- desktop_config_.FindDisplayConfigurationById(current_display_); +- if (config) { +- displays_to_capture.push_back(*config); +- } else { +- RTC_LOG(LS_ERROR) << "The selected screen cannot be found for capturing."; +- return false; +- } +- } else { +- // Capturing the whole desktop. +- displays_to_capture = desktop_config_.displays; +- } +- +- // Create the window list once for all displays. +- CFArrayRef window_list = CreateWindowListWithExclusion(excluded_window_); +- +- for (size_t i = 0; i < displays_to_capture.size(); ++i) { +- const MacDisplayConfiguration& display_config = displays_to_capture[i]; +- +- // Capturing mixed-DPI on one surface is hard, so we only return displays +- // that match the "primary" display's DPI. The primary display is always +- // the first in the list. +- if (i > 0 && display_config.dip_to_pixel_scale != +- displays_to_capture[0].dip_to_pixel_scale) { +- continue; +- } +- // Determine the display's position relative to the desktop, in pixels. +- DesktopRect display_bounds = display_config.pixel_bounds; +- display_bounds.Translate(-screen_pixel_bounds_.left(), +- -screen_pixel_bounds_.top()); +- +- // Determine which parts of the blit region, if any, lay within the monitor. +- DesktopRegion copy_region = region; +- copy_region.IntersectWith(display_bounds); +- if (copy_region.is_empty()) +- continue; +- +- // Translate the region to be copied into display-relative coordinates. +- copy_region.Translate(-display_bounds.left(), -display_bounds.top()); +- +- DesktopRect excluded_window_bounds; +- CGImageRef excluded_image = nullptr; +- if (excluded_window_ && window_list) { +- // Get the region of the excluded window relative the primary display. +- excluded_window_bounds = GetExcludedWindowPixelBounds( +- excluded_window_, display_config.dip_to_pixel_scale); +- excluded_window_bounds.IntersectWith(display_config.pixel_bounds); +- +- // Create the image under the excluded window first, because it's faster +- // than captuing the whole display. +- if (!excluded_window_bounds.is_empty()) { +- excluded_image = CreateExcludedWindowRegionImage( +- excluded_window_bounds, display_config.dip_to_pixel_scale, +- window_list); +- } +- } +- +- // Create an image containing a snapshot of the display. +- CGImageRef image = CGDisplayCreateImage(display_config.id); +- if (!image) { +- if (excluded_image) +- CFRelease(excluded_image); +- continue; +- } +- +- // Verify that the image has 32-bit depth. +- int bits_per_pixel = CGImageGetBitsPerPixel(image); +- if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) { +- RTC_LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " << bits_per_pixel +- << " bits per pixel. Only 32-bit depth is supported."; +- CFRelease(image); +- if (excluded_image) +- CFRelease(excluded_image); +- return false; +- } +- +- // Request access to the raw pixel data via the image's DataProvider. +- CGDataProviderRef provider = CGImageGetDataProvider(image); +- CFDataRef data = CGDataProviderCopyData(provider); +- assert(data); +- +- const uint8_t* display_base_address = CFDataGetBytePtr(data); +- int src_bytes_per_row = CGImageGetBytesPerRow(image); +- +- // |image| size may be different from display_bounds in case the screen was +- // resized recently. +- copy_region.IntersectWith( +- DesktopRect::MakeWH(CGImageGetWidth(image), CGImageGetHeight(image))); +- +- // Copy the dirty region from the display buffer into our desktop buffer. +- uint8_t* out_ptr = frame.GetFrameDataAtPos(display_bounds.top_left()); +- for (DesktopRegion::Iterator i(copy_region); !i.IsAtEnd(); i.Advance()) { +- CopyRect(display_base_address, src_bytes_per_row, out_ptr, frame.stride(), +- DesktopFrame::kBytesPerPixel, i.rect()); +- } +- +- CFRelease(data); +- CFRelease(image); +- +- if (excluded_image) { +- CGDataProviderRef provider = CGImageGetDataProvider(excluded_image); +- CFDataRef excluded_image_data = CGDataProviderCopyData(provider); +- assert(excluded_image_data); +- display_base_address = CFDataGetBytePtr(excluded_image_data); +- src_bytes_per_row = CGImageGetBytesPerRow(excluded_image); +- +- // Translate the bounds relative to the desktop, because |frame| data +- // starts from the desktop top-left corner. +- DesktopRect window_bounds_relative_to_desktop(excluded_window_bounds); +- window_bounds_relative_to_desktop.Translate(-screen_pixel_bounds_.left(), +- -screen_pixel_bounds_.top()); +- +- DesktopRect rect_to_copy = +- DesktopRect::MakeSize(excluded_window_bounds.size()); +- rect_to_copy.IntersectWith(DesktopRect::MakeWH( +- CGImageGetWidth(excluded_image), CGImageGetHeight(excluded_image))); +- +- if (CGImageGetBitsPerPixel(excluded_image) / 8 == +- DesktopFrame::kBytesPerPixel) { +- CopyRect(display_base_address, src_bytes_per_row, +- frame.GetFrameDataAtPos( +- window_bounds_relative_to_desktop.top_left()), +- frame.stride(), DesktopFrame::kBytesPerPixel, rect_to_copy); +- } +- +- CFRelease(excluded_image_data); +- CFRelease(excluded_image); +- } +- } +- if (window_list) +- CFRelease(window_list); +- return true; +-} +- +-void ScreenCapturerMac::ScreenConfigurationChanged() { +- if (current_display_) { +- const MacDisplayConfiguration* config = +- desktop_config_.FindDisplayConfigurationById(current_display_); +- screen_pixel_bounds_ = config ? config->pixel_bounds : DesktopRect(); +- dip_to_pixel_scale_ = config ? config->dip_to_pixel_scale : 1.0f; +- } else { +- screen_pixel_bounds_ = desktop_config_.pixel_bounds; +- dip_to_pixel_scale_ = desktop_config_.dip_to_pixel_scale; +- } +- +- // Release existing buffers, which will be of the wrong size. +- ReleaseBuffers(); +- +- // Clear the dirty region, in case the display is down-sizing. +- helper_.ClearInvalidRegion(); +- +- // Re-mark the entire desktop as dirty. +- helper_.InvalidateScreen(screen_pixel_bounds_.size()); +- +- // Make sure the frame buffers will be reallocated. +- queue_.Reset(); +-} +- +-bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { +- desktop_config_ = desktop_config_monitor_->desktop_configuration(); +- for (const auto& config : desktop_config_.displays) { +- size_t pixel_width = config.pixel_bounds.width(); +- size_t pixel_height = config.pixel_bounds.height(); +- if (pixel_width == 0 || pixel_height == 0) +- continue; +- // Using a local variable forces the block to capture the raw pointer. +- DisplayStreamManager* manager = display_stream_manager_; +- int unique_id = manager->GetUniqueId(); +- CGDirectDisplayID display_id = config.id; +- DesktopVector display_origin = config.pixel_bounds.top_left(); +- +- CGDisplayStreamFrameAvailableHandler handler = +- ^(CGDisplayStreamFrameStatus status, uint64_t display_time, +- IOSurfaceRef frame_surface, CGDisplayStreamUpdateRef updateRef) { +- if (status == kCGDisplayStreamFrameStatusStopped) { +- manager->DestroyStream(unique_id); +- return; +- } +- +- if (manager->ShouldIgnoreUpdates()) +- return; +- +- // Only pay attention to frame updates. +- if (status != kCGDisplayStreamFrameStatusFrameComplete) +- return; +- +- size_t count = 0; +- const CGRect* rects = CGDisplayStreamUpdateGetRects( +- updateRef, kCGDisplayStreamUpdateDirtyRects, &count); +- if (count != 0) { +- // According to CGDisplayStream.h, it's safe to call +- // CGDisplayStreamStop() from within the callback. +- ScreenRefresh(count, rects, display_origin); +- } +- }; +- CGDisplayStreamRef display_stream = CGDisplayStreamCreate( +- display_id, pixel_width, pixel_height, 'BGRA', nullptr, handler); +- +- if (display_stream) { +- CGError error = CGDisplayStreamStart(display_stream); +- if (error != kCGErrorSuccess) +- return false; +- +- CFRunLoopSourceRef source = +- CGDisplayStreamGetRunLoopSource(display_stream); +- CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); +- display_stream_manager_->SaveStream(unique_id, display_stream); +- } +- } +- +- return true; +-} +- +-void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { +- display_stream_manager_->UnregisterActiveStreams(); +-} +- +-void ScreenCapturerMac::ScreenRefresh(CGRectCount count, +- const CGRect* rect_array, +- DesktopVector display_origin) { +- if (screen_pixel_bounds_.is_empty()) +- ScreenConfigurationChanged(); +- +- // The refresh rects are in display coordinates. We want to translate to +- // framebuffer coordinates. If a specific display is being captured, then no +- // change is necessary. If all displays are being captured, then we want to +- // translate by the origin of the display. +- DesktopVector translate_vector; +- if (!current_display_) +- translate_vector = display_origin; +- +- DesktopRegion region; +- for (CGRectCount i = 0; i < count; ++i) { +- // All rects are already in physical pixel coordinates. +- DesktopRect rect = DesktopRect::MakeXYWH( +- rect_array[i].origin.x, rect_array[i].origin.y, +- rect_array[i].size.width, rect_array[i].size.height); +- +- rect.Translate(translate_vector); +- +- region.AddRect(rect); +- } +- +- helper_.InvalidateRegion(region); +-} +- +-std::unique_ptr ScreenCapturerMac::CreateFrame() { +- std::unique_ptr frame( +- new BasicDesktopFrame(screen_pixel_bounds_.size())); +- frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, +- kStandardDPI * dip_to_pixel_scale_)); +- return frame; +-} +- +-} // namespace +- +-// static +-std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( +- const DesktopCaptureOptions& options) { +- if (!options.configuration_monitor()) +- return nullptr; +- +- std::unique_ptr capturer(new ScreenCapturerMac( +- options.configuration_monitor(), options.detect_updated_region())); +- if (!capturer.get()->Init()) { +- return nullptr; +- } +- +- return capturer; +-} +- +-} // namespace webrtc -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0101.patch b/third_party/libwebrtc/moz-patch-stack/0101.patch index 460056611c790..353e57b16419f 100644 --- a/third_party/libwebrtc/moz-patch-stack/0101.patch +++ b/third_party/libwebrtc/moz-patch-stack/0101.patch @@ -1,164 +1,160 @@ From: Andreas Pehrson -Date: Tue, 16 May 2023 06:59:00 +0000 -Subject: Bug 1832717 - Cherry-pick upstream libwebrtc commit 0f87b38535. +Date: Tue, 23 May 2023 06:14:00 +0000 +Subject: Bug 1832751 - cherry-pick upstream libwebrtc commit 301e546a68. r=webrtc-reviewers,mjf -Upstream Commit: https://webrtc.googlesource.com/src/+/0f87b3853554ee5d4e92e487a5165b57771b6742 - mac: Work around an inccorect availability annotation in the 13.3 SDK +Upstream commit: https://webrtc.googlesource.com/src/+/301e546a689020320f919a660591759e993ef051 + Remove SequenceCheckerImpl::valid_system_queue_ - Bug: chromium:1431897 - Change-Id: Ib871dc22d2cf93180d7aa05016e34ffec944d73e - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301040 - Reviewed-by: Alexander Cooper - Commit-Queue: Alexander Cooper - Auto-Submit: Nico Weber - Cr-Commit-Position: refs/heads/main@{#39830} + As pointed out in issue webrtc:15146 this Mac/iOS specific variable, + makes the SequenceChecker behave incorrectly on those platforms. -Differential Revision: https://phabricator.services.mozilla.com/D178027 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8443a5cec0ac1273f70cee116f08b88d0c19788d + The variable was introduced in a CL that merged the previous checker + classes, ThreadChecker and SequencedTaskChecker, but curiously neither + one of them had such a variable. So I'm not exactly sure what problem + was being solved. Hence I'm wondering if we actually need it. + + Reference: https://webrtc-review.googlesource.com/c/src/+/129721 + + Bug: webrtc:15146 + Change-Id: Ia7a9eb17b993c4f8a1e8204c658bf0b3dbdaa1e0 + Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304401 + Reviewed-by: Peter Hanspers + Commit-Queue: Tomas Gunnarsson + Cr-Commit-Position: refs/heads/main@{#40019} + +Differential Revision: https://phabricator.services.mozilla.com/D177875 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/220fde5226ae38aa03a625b6a472b6e6ef6b6054 --- - .../mac/screen_capturer_mac.mm | 97 +++++++++++++++++-- - 1 file changed, 89 insertions(+), 8 deletions(-) + api/sequence_checker_unittest.cc | 13 +++++++ + .../sequence_checker_internal.cc | 37 +++---------------- + .../sequence_checker_internal.h | 1 - + 3 files changed, 18 insertions(+), 33 deletions(-) -diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm -index cad0c5b65b..76fec13a39 100644 ---- a/modules/desktop_capture/mac/screen_capturer_mac.mm -+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm -@@ -20,6 +20,87 @@ - #include "rtc_base/trace_event.h" - #include "sdk/objc/helpers/scoped_cftyperef.h" +diff --git a/api/sequence_checker_unittest.cc b/api/sequence_checker_unittest.cc +index 3efb5c78ee..f117926d73 100644 +--- a/api/sequence_checker_unittest.cc ++++ b/api/sequence_checker_unittest.cc +@@ -98,6 +98,19 @@ TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) { + [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); }); + } -+// All these symbols have incorrect availability annotations in the 13.3 SDK. -+// These have the correct annotation. See https://crbug.com/1431897. -+// TODO(thakis): Remove this once FB12109479 is fixed and we updated to an SDK -+// with the fix. -+ -+static CGDisplayStreamRef __nullable -+ wrapCGDisplayStreamCreate(CGDirectDisplayID display, -+ size_t outputWidth, -+ size_t outputHeight, -+ int32_t pixelFormat, -+ CFDictionaryRef __nullable properties, -+ CGDisplayStreamFrameAvailableHandler __nullable handler) -+ CG_AVAILABLE_BUT_DEPRECATED( -+ 10.8, -+ 14.0, -+ "Please use ScreenCaptureKit API's initWithFilter:configuration:delegate: instead") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return CGDisplayStreamCreate( -+ display, outputWidth, outputHeight, pixelFormat, properties, handler); -+#pragma clang diagnostic pop -+} -+ -+static CFRunLoopSourceRef __nullable -+ wrapCGDisplayStreamGetRunLoopSource(CGDisplayStreamRef cg_nullable displayStream) -+ CG_AVAILABLE_BUT_DEPRECATED(10.8, -+ 14.0, -+ "There is no direct replacement for this function. Please use " -+ "ScreenCaptureKit API's SCStream to replace CGDisplayStream") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return CGDisplayStreamGetRunLoopSource(displayStream); -+#pragma clang diagnostic pop -+} -+ -+static CGError wrapCGDisplayStreamStart(CGDisplayStreamRef cg_nullable displayStream) -+ CG_AVAILABLE_BUT_DEPRECATED(10.8, -+ 14.0, -+ "Please use ScreenCaptureKit API's " -+ "startCaptureWithCompletionHandler: to start a stream instead") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return CGDisplayStreamStart(displayStream); -+#pragma clang diagnostic pop -+} -+ -+static CGError wrapCGDisplayStreamStop(CGDisplayStreamRef cg_nullable displayStream) -+ CG_AVAILABLE_BUT_DEPRECATED(10.8, -+ 14.0, -+ "Please use ScreenCaptureKit API's " -+ "stopCaptureWithCompletionHandler: to stop a stream instead") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return CGDisplayStreamStop(displayStream); -+#pragma clang diagnostic pop ++#if RTC_DCHECK_IS_ON ++TEST(SequenceCheckerTest, OnlyCurrentOnOneThread) { ++ SequenceChecker sequence_checker(SequenceChecker::kDetached); ++ RunOnDifferentThread([&] { ++ EXPECT_TRUE(sequence_checker.IsCurrent()); ++ // Spawn a new thread from within the first one to guarantee that we have ++ // two concurrently active threads (and that there's no chance of the ++ // thread ref being reused). ++ RunOnDifferentThread([&] { EXPECT_FALSE(sequence_checker.IsCurrent()); }); ++ }); +} ++#endif + -+static CFStringRef wrapkCGDisplayStreamShowCursor() CG_AVAILABLE_BUT_DEPRECATED( -+ 10.8, -+ 14.0, -+ "Please use ScreenCaptureKit API's SCStreamConfiguration showsCursor property instead") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return kCGDisplayStreamShowCursor; -+#pragma clang diagnostic pop -+} -+ -+static const CGRect* __nullable -+ wrapCGDisplayStreamUpdateGetRects(CGDisplayStreamUpdateRef __nullable updateRef, -+ CGDisplayStreamUpdateRectType rectType, -+ size_t* rectCount) -+ CG_AVAILABLE_BUT_DEPRECATED(10.8, -+ 14.0, -+ "Please use ScreenCaptureKit API's SCStreamFrameInfo with " -+ "SCStreamFrameInfoContentRect instead") { -+#pragma clang diagnostic push -+#pragma clang diagnostic ignored "-Wunguarded-availability-new" -+ return CGDisplayStreamUpdateGetRects(updateRef, rectType, rectCount); -+#pragma clang diagnostic pop -+} -+ - namespace webrtc { + TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) { + SequenceChecker sequence_checker; + TaskQueueForTest queue; +diff --git a/rtc_base/synchronization/sequence_checker_internal.cc b/rtc_base/synchronization/sequence_checker_internal.cc +index 9831f07d7d..3e205b91d5 100644 +--- a/rtc_base/synchronization/sequence_checker_internal.cc ++++ b/rtc_base/synchronization/sequence_checker_internal.cc +@@ -11,52 +11,30 @@ - namespace { -@@ -462,7 +543,7 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { + #include - size_t count = 0; - const CGRect* rects = -- CGDisplayStreamUpdateGetRects(updateRef, kCGDisplayStreamUpdateDirtyRects, &count); -+ wrapCGDisplayStreamUpdateGetRects(updateRef, kCGDisplayStreamUpdateDirtyRects, &count); - if (count != 0) { - // According to CGDisplayStream.h, it's safe to call - // CGDisplayStreamStop() from within the callback. -@@ -472,20 +553,20 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { +-#if defined(WEBRTC_MAC) +-#include +-#endif +- + #include "rtc_base/checks.h" + #include "rtc_base/strings/string_builder.h" - rtc::ScopedCFTypeRef properties_dict( - CFDictionaryCreate(kCFAllocatorDefault, -- (const void* []){kCGDisplayStreamShowCursor}, -- (const void* []){kCFBooleanFalse}, -+ (const void*[]){wrapkCGDisplayStreamShowCursor()}, -+ (const void*[]){kCFBooleanFalse}, - 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks)); + namespace webrtc { + namespace webrtc_sequence_checker_internal { +-namespace { +-// On Mac, returns the label of the current dispatch queue; elsewhere, return +-// null. +-const void* GetSystemQueueRef() { +-#if defined(WEBRTC_MAC) +- return dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); +-#else +- return nullptr; +-#endif +-} +- +-} // namespace -- CGDisplayStreamRef display_stream = CGDisplayStreamCreate( -+ CGDisplayStreamRef display_stream = wrapCGDisplayStreamCreate( - display_id, pixel_width, pixel_height, 'BGRA', properties_dict.get(), handler); + SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread) + : attached_(attach_to_current_thread), + valid_thread_(rtc::CurrentThreadRef()), +- valid_queue_(TaskQueueBase::Current()), +- valid_system_queue_(GetSystemQueueRef()) {} ++ valid_queue_(TaskQueueBase::Current()) {} - if (display_stream) { -- CGError error = CGDisplayStreamStart(display_stream); -+ CGError error = wrapCGDisplayStreamStart(display_stream); - if (error != kCGErrorSuccess) return false; + bool SequenceCheckerImpl::IsCurrent() const { + const TaskQueueBase* const current_queue = TaskQueueBase::Current(); + const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); +- const void* const current_system_queue = GetSystemQueueRef(); + MutexLock scoped_lock(&lock_); + if (!attached_) { // Previously detached. + attached_ = true; + valid_thread_ = current_thread; + valid_queue_ = current_queue; +- valid_system_queue_ = current_system_queue; + return true; + } + if (valid_queue_) { + return valid_queue_ == current_queue; + } +- if (valid_system_queue_ && valid_system_queue_ == current_system_queue) { +- return true; +- } + return rtc::IsThreadRefEqual(valid_thread_, current_thread); + } -- CFRunLoopSourceRef source = CGDisplayStreamGetRunLoopSource(display_stream); -+ CFRunLoopSourceRef source = wrapCGDisplayStreamGetRunLoopSource(display_stream); - CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); - display_streams_.push_back(display_stream); - } -@@ -498,9 +579,9 @@ void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { - RTC_DCHECK(thread_checker_.IsCurrent()); +@@ -71,7 +49,6 @@ void SequenceCheckerImpl::Detach() { + std::string SequenceCheckerImpl::ExpectationToString() const { + const TaskQueueBase* const current_queue = TaskQueueBase::Current(); + const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); +- const void* const current_system_queue = GetSystemQueueRef(); + MutexLock scoped_lock(&lock_); + if (!attached_) + return "Checker currently not attached."; +@@ -85,17 +62,13 @@ std::string SequenceCheckerImpl::ExpectationToString() const { - for (CGDisplayStreamRef stream : display_streams_) { -- CFRunLoopSourceRef source = CGDisplayStreamGetRunLoopSource(stream); -+ CFRunLoopSourceRef source = wrapCGDisplayStreamGetRunLoopSource(stream); - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); -- CGDisplayStreamStop(stream); -+ wrapCGDisplayStreamStop(stream); - CFRelease(stream); + rtc::StringBuilder message; + message.AppendFormat( +- "# Expected: TQ: %p SysQ: %p Thread: %p\n" +- "# Actual: TQ: %p SysQ: %p Thread: %p\n", +- valid_queue_, valid_system_queue_, +- reinterpret_cast(valid_thread_), current_queue, +- current_system_queue, reinterpret_cast(current_thread)); ++ "# Expected: TQ: %p Thread: %p\n" ++ "# Actual: TQ: %p Thread: %p\n", ++ valid_queue_, reinterpret_cast(valid_thread_), current_queue, ++ reinterpret_cast(current_thread)); + + if ((valid_queue_ || current_queue) && valid_queue_ != current_queue) { + message << "TaskQueue doesn't match\n"; +- } else if (valid_system_queue_ && +- valid_system_queue_ != current_system_queue) { +- message << "System queue doesn't match\n"; + } else if (!rtc::IsThreadRefEqual(valid_thread_, current_thread)) { + message << "Threads don't match\n"; } - display_streams_.clear(); +diff --git a/rtc_base/synchronization/sequence_checker_internal.h b/rtc_base/synchronization/sequence_checker_internal.h +index a66e9ee8ec..22503027a5 100644 +--- a/rtc_base/synchronization/sequence_checker_internal.h ++++ b/rtc_base/synchronization/sequence_checker_internal.h +@@ -50,7 +50,6 @@ class RTC_EXPORT SequenceCheckerImpl { + mutable bool attached_ RTC_GUARDED_BY(lock_); + mutable rtc::PlatformThreadRef valid_thread_ RTC_GUARDED_BY(lock_); + mutable const TaskQueueBase* valid_queue_ RTC_GUARDED_BY(lock_); +- mutable const void* valid_system_queue_ RTC_GUARDED_BY(lock_); + }; + + // Do nothing implementation, for use in release mode. -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0102.patch b/third_party/libwebrtc/moz-patch-stack/0102.patch index 263f9c50b9276..4769543fc8fc1 100644 --- a/third_party/libwebrtc/moz-patch-stack/0102.patch +++ b/third_party/libwebrtc/moz-patch-stack/0102.patch @@ -1,38 +1,66 @@ From: Andreas Pehrson -Date: Wed, 17 May 2023 08:25:00 +0000 -Subject: Bug 1830945 - Do not lock in VideoCaptureDS::{Start|Stop}Capture. - r=padenot +Date: Tue, 23 May 2023 06:14:00 +0000 +Subject: Bug 1809672 - Refactor TabCapturerWebrtc creation. + r=ng,webrtc-reviewers -Unclear what they are guarding. +This restores libwebrtc's DesktopCapturer to their upstream state as far as +the tab capturer is concerned. -Differential Revision: https://phabricator.services.mozilla.com/D178279 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fcd48e81c9c2cb68ea2cb3d44b3574281be2154e +Differential Revision: https://phabricator.services.mozilla.com/D174290 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/3778b2a0e3f93a2077303b91739cdd2eeb590726 --- - modules/video_capture/windows/video_capture_ds.cc | 4 ---- - 1 file changed, 4 deletions(-) + modules/desktop_capture/desktop_capturer.cc | 11 ----------- + modules/desktop_capture/desktop_capturer.h | 8 -------- + 2 files changed, 19 deletions(-) -diff --git a/modules/video_capture/windows/video_capture_ds.cc b/modules/video_capture/windows/video_capture_ds.cc -index 8695f76245..b13ac074f8 100644 ---- a/modules/video_capture/windows/video_capture_ds.cc -+++ b/modules/video_capture/windows/video_capture_ds.cc -@@ -122,8 +122,6 @@ int32_t VideoCaptureDS::Init(const char* deviceUniqueIdUTF8) { +diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc +index 1af19a1fd2..7f601821fc 100644 +--- a/modules/desktop_capture/desktop_capturer.cc ++++ b/modules/desktop_capture/desktop_capturer.cc +@@ -128,17 +128,6 @@ std::unique_ptr DesktopCapturer::CreateScreenCapturer( + return capturer; } - int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { -- MutexLock lock(&api_lock_); +-// static +-std::unique_ptr DesktopCapturer::CreateTabCapturer( +- const DesktopCaptureOptions& options) { +- std::unique_ptr capturer = CreateRawTabCapturer(options); +- if (capturer && options.detect_updated_region()) { +- capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); +- } - - if (capability != _requestedCapability) { - DisconnectGraph(); +- return capturer; +-} +- + #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + bool DesktopCapturer::IsRunningUnderWayland() { + const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); +diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h +index 64f3187f51..5efd2efc0f 100644 +--- a/modules/desktop_capture/desktop_capturer.h ++++ b/modules/desktop_capture/desktop_capturer.h +@@ -191,10 +191,6 @@ class RTC_EXPORT DesktopCapturer { + static std::unique_ptr CreateScreenCapturer( + const DesktopCaptureOptions& options); -@@ -146,8 +144,6 @@ int32_t VideoCaptureDS::StartCapture(const VideoCaptureCapability& capability) { - } +- // Creates a DesktopCapturer instance which targets to capture tab. +- static std::unique_ptr CreateTabCapturer( +- const DesktopCaptureOptions& options); +- + #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + static bool IsRunningUnderWayland(); - int32_t VideoCaptureDS::StopCapture() { -- MutexLock lock(&api_lock_); +@@ -225,10 +221,6 @@ class RTC_EXPORT DesktopCapturer { + // capture screens. + static std::unique_ptr CreateRawScreenCapturer( + const DesktopCaptureOptions& options); - - HRESULT hr = _mediaControl->StopWhenReady(); - if (FAILED(hr)) { - RTC_LOG(LS_INFO) << "Failed to stop the capture graph. " << hr; +- // Creates a DesktopCapturer instance which targets to capture tabs +- static std::unique_ptr CreateRawTabCapturer( +- const DesktopCaptureOptions& options); + }; + + } // namespace webrtc -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0103.patch b/third_party/libwebrtc/moz-patch-stack/0103.patch index 4f2b31301a854..573a4f96d212c 100644 --- a/third_party/libwebrtc/moz-patch-stack/0103.patch +++ b/third_party/libwebrtc/moz-patch-stack/0103.patch @@ -1,789 +1,58 @@ -From: Andreas Pehrson -Date: Wed, 17 May 2023 13:30:00 +0000 -Subject: Bug 1833101 - From libwebrtc, remove - desktop_capture/screen_capturer_mac.mm. r=mjf,webrtc-reviewers +From: Nico Grunbaum +Date: Tue, 6 Jun 2023 16:37:00 -0700 +Subject: Bug 1833237 - (fix-f0be3bee1f) remove reference to + portal:pipewire_base;r?pehrsons -This is code existing only in our local copy. - -Differential Revision: https://phabricator.services.mozilla.com/D178026 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/92458cfcd52ce53b2f25ba9604fe70ef7f8054d4 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8ff886a4d366b4be35b329d1ef733a6df542067c --- - .../desktop_capture/screen_capturer_mac.mm | 766 ------------------ - 1 file changed, 766 deletions(-) - delete mode 100644 modules/desktop_capture/screen_capturer_mac.mm + modules/video_capture/BUILD.gn | 4 ++++ + modules/video_capture/linux/device_info_pipewire.cc | 3 ++- + modules/video_capture/linux/device_info_pipewire.h | 3 ++- + 3 files changed, 8 insertions(+), 2 deletions(-) -diff --git a/modules/desktop_capture/screen_capturer_mac.mm b/modules/desktop_capture/screen_capturer_mac.mm -deleted file mode 100644 -index 285086ffa6..0000000000 ---- a/modules/desktop_capture/screen_capturer_mac.mm -+++ /dev/null -@@ -1,766 +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 -- --#include --#include --#include -- --#include --#include --#include -- --#include "modules/desktop_capture/desktop_capture_options.h" --#include "modules/desktop_capture/desktop_capturer.h" --#include "modules/desktop_capture/desktop_frame.h" --#include "modules/desktop_capture/desktop_geometry.h" --#include "modules/desktop_capture/desktop_region.h" --#include "modules/desktop_capture/mac/desktop_configuration.h" --#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" --#include "modules/desktop_capture/mac/scoped_pixel_buffer_object.h" --#include "modules/desktop_capture/screen_capture_frame_queue.h" --#include "modules/desktop_capture/screen_capturer_helper.h" --#include "modules/desktop_capture/shared_desktop_frame.h" --#include "rtc_base/checks.h" --#include "rtc_base/constructormagic.h" --#include "rtc_base/logging.h" --#include "rtc_base/macutils.h" --#include "rtc_base/timeutils.h" -- --namespace webrtc { -- --namespace { -- --// CGDisplayStreamRefs need to be destroyed asynchronously after receiving a --// kCGDisplayStreamFrameStatusStopped callback from CoreGraphics. This may --// happen after the ScreenCapturerMac has been destroyed. DisplayStreamManager --// is responsible for destroying all extant CGDisplayStreamRefs, and will --// destroy itself once it's done. --class DisplayStreamManager { -- public: -- int GetUniqueId() { return ++unique_id_generator_; } -- void DestroyStream(int unique_id) { -- auto it = display_stream_wrappers_.find(unique_id); -- RTC_CHECK(it != display_stream_wrappers_.end()); -- RTC_CHECK(!it->second.active); -- CFRelease(it->second.stream); -- display_stream_wrappers_.erase(it); -- -- if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) -- delete this; -- } -- -- void SaveStream(int unique_id, -- CGDisplayStreamRef stream) { -- RTC_CHECK(unique_id <= unique_id_generator_); -- DisplayStreamWrapper wrapper; -- wrapper.stream = stream; -- display_stream_wrappers_[unique_id] = wrapper; -- } -- -- void UnregisterActiveStreams() { -- for (auto& pair : display_stream_wrappers_) { -- DisplayStreamWrapper& wrapper = pair.second; -- if (wrapper.active) { -- wrapper.active = false; -- CFRunLoopSourceRef source = -- CGDisplayStreamGetRunLoopSource(wrapper.stream); -- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, -- kCFRunLoopCommonModes); -- CGDisplayStreamStop(wrapper.stream); -- } -- } -- } -- -- void PrepareForSelfDestruction() { -- ready_for_self_destruction_ = true; -- -- if (display_stream_wrappers_.empty()) -- delete this; -- } -- -- // Once the DisplayStreamManager is ready for destruction, the -- // ScreenCapturerMac is no longer present. Any updates should be ignored. -- bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; } -- -- private: -- struct DisplayStreamWrapper { -- // The registered CGDisplayStreamRef. -- CGDisplayStreamRef stream = nullptr; -- -- // Set to false when the stream has been stopped. An asynchronous callback -- // from CoreGraphics will let us destroy the CGDisplayStreamRef. -- bool active = true; -- }; -- -- std::map display_stream_wrappers_; -- int unique_id_generator_ = 0; -- bool ready_for_self_destruction_ = false; --}; -- --// Standard Mac displays have 72dpi, but we report 96dpi for --// consistency with Windows and Linux. --const int kStandardDPI = 96; -- --// Scales all coordinates of a rect by a specified factor. --DesktopRect ScaleAndRoundCGRect(const CGRect& rect, float scale) { -- return DesktopRect::MakeLTRB( -- static_cast(floor(rect.origin.x * scale)), -- static_cast(floor(rect.origin.y * scale)), -- static_cast(ceil((rect.origin.x + rect.size.width) * scale)), -- static_cast(ceil((rect.origin.y + rect.size.height) * scale))); --} -- --// Copy pixels in the |rect| from |src_place| to |dest_plane|. |rect| should be --// relative to the origin of |src_plane| and |dest_plane|. --void CopyRect(const uint8_t* src_plane, -- int src_plane_stride, -- uint8_t* dest_plane, -- int dest_plane_stride, -- int bytes_per_pixel, -- const DesktopRect& rect) { -- // Get the address of the starting point. -- const int src_y_offset = src_plane_stride * rect.top(); -- const int dest_y_offset = dest_plane_stride * rect.top(); -- const int x_offset = bytes_per_pixel * rect.left(); -- src_plane += src_y_offset + x_offset; -- dest_plane += dest_y_offset + x_offset; -- -- // Copy pixels in the rectangle line by line. -- const int bytes_per_line = bytes_per_pixel * rect.width(); -- const int height = rect.height(); -- for (int i = 0 ; i < height; ++i) { -- memcpy(dest_plane, src_plane, bytes_per_line); -- src_plane += src_plane_stride; -- dest_plane += dest_plane_stride; -- } --} -- --// Returns an array of CGWindowID for all the on-screen windows except --// |window_to_exclude|, or NULL if the window is not found or it fails. The --// caller should release the returned CFArrayRef. --CFArrayRef CreateWindowListWithExclusion(CGWindowID window_to_exclude) { -- if (!window_to_exclude) -- return nullptr; -- -- CFArrayRef all_windows = CGWindowListCopyWindowInfo( -- kCGWindowListOptionOnScreenOnly, kCGNullWindowID); -- if (!all_windows) -- return nullptr; -- -- CFMutableArrayRef returned_array = -- CFArrayCreateMutable(nullptr, CFArrayGetCount(all_windows), nullptr); -- -- bool found = false; -- for (CFIndex i = 0; i < CFArrayGetCount(all_windows); ++i) { -- CFDictionaryRef window = reinterpret_cast( -- CFArrayGetValueAtIndex(all_windows, i)); -- -- CFNumberRef id_ref = reinterpret_cast( -- CFDictionaryGetValue(window, kCGWindowNumber)); -- -- CGWindowID id; -- CFNumberGetValue(id_ref, kCFNumberIntType, &id); -- if (id == window_to_exclude) { -- found = true; -- continue; -- } -- CFArrayAppendValue(returned_array, reinterpret_cast(id)); -- } -- CFRelease(all_windows); -- -- if (!found) { -- CFRelease(returned_array); -- returned_array = nullptr; -- } -- return returned_array; --} -- --// Returns the bounds of |window| in physical pixels, enlarged by a small amount --// on four edges to take account of the border/shadow effects. --DesktopRect GetExcludedWindowPixelBounds(CGWindowID window, -- float dip_to_pixel_scale) { -- // The amount of pixels to add to the actual window bounds to take into -- // account of the border/shadow effects. -- static const int kBorderEffectSize = 20; -- CGRect rect; -- CGWindowID ids[1]; -- ids[0] = window; -- -- CFArrayRef window_id_array = -- CFArrayCreate(nullptr, reinterpret_cast(&ids), 1, nullptr); -- CFArrayRef window_array = -- CGWindowListCreateDescriptionFromArray(window_id_array); -- -- if (CFArrayGetCount(window_array) > 0) { -- CFDictionaryRef window = reinterpret_cast( -- CFArrayGetValueAtIndex(window_array, 0)); -- CFDictionaryRef bounds_ref = reinterpret_cast( -- CFDictionaryGetValue(window, kCGWindowBounds)); -- CGRectMakeWithDictionaryRepresentation(bounds_ref, &rect); -- } -- -- CFRelease(window_id_array); -- CFRelease(window_array); -- -- rect.origin.x -= kBorderEffectSize; -- rect.origin.y -= kBorderEffectSize; -- rect.size.width += kBorderEffectSize * 2; -- rect.size.height += kBorderEffectSize * 2; -- // |rect| is in DIP, so convert to physical pixels. -- return ScaleAndRoundCGRect(rect, dip_to_pixel_scale); --} -- --// Create an image of the given region using the given |window_list|. --// |pixel_bounds| should be in the primary display's coordinate in physical --// pixels. The caller should release the returned CGImageRef and CFDataRef. --CGImageRef CreateExcludedWindowRegionImage(const DesktopRect& pixel_bounds, -- float dip_to_pixel_scale, -- CFArrayRef window_list) { -- CGRect window_bounds; -- // The origin is in DIP while the size is in physical pixels. That's what -- // CGWindowListCreateImageFromArray expects. -- window_bounds.origin.x = pixel_bounds.left() / dip_to_pixel_scale; -- window_bounds.origin.y = pixel_bounds.top() / dip_to_pixel_scale; -- window_bounds.size.width = pixel_bounds.width(); -- window_bounds.size.height = pixel_bounds.height(); -- -- return CGWindowListCreateImageFromArray( -- window_bounds, window_list, kCGWindowImageDefault); --} -- --// A class to perform video frame capturing for mac. --class ScreenCapturerMac : public DesktopCapturer { -- public: -- explicit ScreenCapturerMac( -- rtc::scoped_refptr desktop_config_monitor, -- bool detect_updated_region); -- ~ScreenCapturerMac() override; -- -- bool Init(); -- -- // DesktopCapturer interface. -- void Start(Callback* callback) override; -- void CaptureFrame() override; -- void SetExcludedWindow(WindowId window) override; -- bool GetSourceList(SourceList* screens) override; -- bool SelectSource(SourceId id) override; -- -- private: -- // Returns false if the selected screen is no longer valid. -- bool CgBlit(const DesktopFrame& frame, const DesktopRegion& region); -- -- // Called when the screen configuration is changed. -- void ScreenConfigurationChanged(); -- -- bool RegisterRefreshAndMoveHandlers(); -- void UnregisterRefreshAndMoveHandlers(); -- -- void ScreenRefresh(CGRectCount count, -- const CGRect *rect_array, -- DesktopVector display_origin); -- void ReleaseBuffers(); -- -- std::unique_ptr CreateFrame(); -- -- const bool detect_updated_region_; -- -- Callback* callback_ = nullptr; -- -- ScopedPixelBufferObject pixel_buffer_object_; -- -- // Queue of the frames buffers. -- ScreenCaptureFrameQueue queue_; -- -- // Current display configuration. -- MacDesktopConfiguration desktop_config_; -- -- // Currently selected display, or 0 if the full desktop is selected. On OS X -- // 10.6 and before, this is always 0. -- CGDirectDisplayID current_display_ = 0; -- -- // The physical pixel bounds of the current screen. -- DesktopRect screen_pixel_bounds_; -- -- // The dip to physical pixel scale of the current screen. -- float dip_to_pixel_scale_ = 1.0f; -- -- // A thread-safe list of invalid rectangles, and the size of the most -- // recently captured screen. -- ScreenCapturerHelper helper_; -- -- // Contains an invalid region from the previous capture. -- DesktopRegion last_invalid_region_; -- -- // Monitoring display reconfiguration. -- rtc::scoped_refptr desktop_config_monitor_; -- -- CGWindowID excluded_window_ = 0; -- -- // A self-owned object that will destroy itself after ScreenCapturerMac and -- // all display streams have been destroyed.. -- DisplayStreamManager* display_stream_manager_; -- -- // Used to force CaptureFrame to update it's screen configuration -- // and reregister event handlers. This ensure that this -- // occurs on the ScreenCapture thread. Read and written from -- // both the VideoCapture thread and ScreenCapture thread. -- // Protected by desktop_config_monitor_. -- bool update_screen_configuration_ = false; -- -- RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); --}; -- --// DesktopFrame wrapper that flips wrapped frame upside down by inverting --// stride. --class InvertedDesktopFrame : public DesktopFrame { -- public: -- InvertedDesktopFrame(std::unique_ptr frame) -- : DesktopFrame( -- frame->size(), -- -frame->stride(), -- frame->data() + (frame->size().height() - 1) * frame->stride(), -- frame->shared_memory()) { -- original_frame_ = std::move(frame); -- MoveFrameInfoFrom(original_frame_.get()); -- } -- ~InvertedDesktopFrame() override {} -- -- private: -- std::unique_ptr original_frame_; -- -- RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); --}; -- --ScreenCapturerMac::ScreenCapturerMac( -- rtc::scoped_refptr desktop_config_monitor, -- bool detect_updated_region) -- : detect_updated_region_(detect_updated_region), -- desktop_config_monitor_(desktop_config_monitor) { -- display_stream_manager_ = new DisplayStreamManager; --} -- --ScreenCapturerMac::~ScreenCapturerMac() { -- ReleaseBuffers(); -- UnregisterRefreshAndMoveHandlers(); -- display_stream_manager_->PrepareForSelfDestruction(); --} -- --bool ScreenCapturerMac::Init() { -- desktop_config_monitor_->Lock(); -- desktop_config_ = desktop_config_monitor_->desktop_configuration(); -- desktop_config_monitor_->Unlock(); -- if (!RegisterRefreshAndMoveHandlers()) { -- return false; -- } -- ScreenConfigurationChanged(); -- return true; --} -- --void ScreenCapturerMac::ReleaseBuffers() { -- // The buffers might be in use by the encoder, so don't delete them here. -- // Instead, mark them as "needs update"; next time the buffers are used by -- // the capturer, they will be recreated if necessary. -- queue_.Reset(); --} -- --void ScreenCapturerMac::Start(Callback* callback) { -- assert(!callback_); -- assert(callback); -- -- callback_ = callback; -- desktop_config_monitor_->Lock(); -- update_screen_configuration_ = true; -- desktop_config_monitor_->Unlock(); --} -- --void ScreenCapturerMac::CaptureFrame() { -- int64_t capture_start_time_nanos = rtc::TimeNanos(); -- -- // Spin RunLoop for 1/100th of a second, handling at most one source -- CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true); -- -- queue_.MoveToNextFrame(); -- RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared()); -- -- desktop_config_monitor_->Lock(); -- MacDesktopConfiguration new_config = -- desktop_config_monitor_->desktop_configuration(); -- if (update_screen_configuration_ || !desktop_config_.Equals(new_config)) { -- update_screen_configuration_ = false; -- desktop_config_ = new_config; -- // If the display configuraiton has changed then refresh capturer data -- // structures. Occasionally, the refresh and move handlers are lost when -- // the screen mode changes, so re-register them here. -- UnregisterRefreshAndMoveHandlers(); -- RegisterRefreshAndMoveHandlers(); -- ScreenConfigurationChanged(); -- } -- -- DesktopRegion region; -- helper_.TakeInvalidRegion(®ion); -- -- // If the current buffer is from an older generation then allocate a new one. -- // Note that we can't reallocate other buffers at this point, since the caller -- // may still be reading from them. -- if (!queue_.current_frame()) -- queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(CreateFrame())); -- -- DesktopFrame* current_frame = queue_.current_frame(); -- -- if (!CgBlit(*current_frame, region)) { -- desktop_config_monitor_->Unlock(); -- callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); -- return; -- } -- std::unique_ptr new_frame = queue_.current_frame()->Share(); -- if (detect_updated_region_) { -- *new_frame->mutable_updated_region() = region; -- } else { -- new_frame->mutable_updated_region()->AddRect( -- DesktopRect::MakeSize(new_frame->size())); -- } -- -- if (current_display_) { -- const MacDisplayConfiguration* config = -- desktop_config_.FindDisplayConfigurationById(current_display_); -- if (config) { -- new_frame->set_top_left(config->bounds.top_left().subtract( -- desktop_config_.bounds.top_left())); -- } -- } -- -- helper_.set_size_most_recent(new_frame->size()); -- -- // Signal that we are done capturing data from the display framebuffer, -- // and accessing display structures. -- desktop_config_monitor_->Unlock(); -- -- new_frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / -- rtc::kNumNanosecsPerMillisec); -- callback_->OnCaptureResult(Result::SUCCESS, std::move(new_frame)); --} -- --void ScreenCapturerMac::SetExcludedWindow(WindowId window) { -- excluded_window_ = window; --} -- --bool ScreenCapturerMac::GetSourceList(SourceList* screens) { -- assert(screens->size() == 0); -- -- for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin(); -- it != desktop_config_.displays.end(); ++it) { -- screens->push_back({it->id}); -- } -- return true; --} -- --bool ScreenCapturerMac::SelectSource(SourceId id) { -- if (id == kFullDesktopScreenId) { -- current_display_ = 0; -- } else { -- const MacDisplayConfiguration* config = -- desktop_config_.FindDisplayConfigurationById( -- static_cast(id)); -- if (!config) -- return false; -- current_display_ = config->id; -- } -- -- ScreenConfigurationChanged(); -- return true; --} -- --bool ScreenCapturerMac::CgBlit(const DesktopFrame& frame, const DesktopRegion& region) { -- // Copy the entire contents of the previous capture buffer, to capture over. -- // TODO(wez): Get rid of this as per crbug.com/145064, or implement -- // crbug.com/92354. -- if (queue_.previous_frame()) { -- memcpy(frame.data(), queue_.previous_frame()->data(), -- frame.stride() * frame.size().height()); -- } -- -- MacDisplayConfigurations displays_to_capture; -- if (current_display_) { -- // Capturing a single screen. Note that the screen id may change when -- // screens are added or removed. -- const MacDisplayConfiguration* config = -- desktop_config_.FindDisplayConfigurationById(current_display_); -- if (config) { -- displays_to_capture.push_back(*config); -- } else { -- RTC_LOG(LS_ERROR) << "The selected screen cannot be found for capturing."; -- return false; -- } -- } else { -- // Capturing the whole desktop. -- displays_to_capture = desktop_config_.displays; -- } -- -- // Create the window list once for all displays. -- CFArrayRef window_list = CreateWindowListWithExclusion(excluded_window_); -- -- for (size_t i = 0; i < displays_to_capture.size(); ++i) { -- const MacDisplayConfiguration& display_config = displays_to_capture[i]; -- -- // Capturing mixed-DPI on one surface is hard, so we only return displays -- // that match the "primary" display's DPI. The primary display is always -- // the first in the list. -- if (i > 0 && display_config.dip_to_pixel_scale != -- displays_to_capture[0].dip_to_pixel_scale) { -- continue; -- } -- // Determine the display's position relative to the desktop, in pixels. -- DesktopRect display_bounds = display_config.pixel_bounds; -- display_bounds.Translate(-screen_pixel_bounds_.left(), -- -screen_pixel_bounds_.top()); -- -- // Determine which parts of the blit region, if any, lay within the monitor. -- DesktopRegion copy_region = region; -- copy_region.IntersectWith(display_bounds); -- if (copy_region.is_empty()) -- continue; -- -- // Translate the region to be copied into display-relative coordinates. -- copy_region.Translate(-display_bounds.left(), -display_bounds.top()); -- -- DesktopRect excluded_window_bounds; -- CGImageRef excluded_image = nullptr; -- if (excluded_window_ && window_list) { -- // Get the region of the excluded window relative the primary display. -- excluded_window_bounds = GetExcludedWindowPixelBounds( -- excluded_window_, display_config.dip_to_pixel_scale); -- excluded_window_bounds.IntersectWith(display_config.pixel_bounds); -- -- // Create the image under the excluded window first, because it's faster -- // than captuing the whole display. -- if (!excluded_window_bounds.is_empty()) { -- excluded_image = CreateExcludedWindowRegionImage( -- excluded_window_bounds, display_config.dip_to_pixel_scale, -- window_list); -- } -- } -- -- // Create an image containing a snapshot of the display. -- CGImageRef image = CGDisplayCreateImage(display_config.id); -- if (!image) { -- if (excluded_image) -- CFRelease(excluded_image); -- continue; -- } -- -- // Verify that the image has 32-bit depth. -- int bits_per_pixel = CGImageGetBitsPerPixel(image); -- if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) { -- RTC_LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " << bits_per_pixel -- << " bits per pixel. Only 32-bit depth is supported."; -- CFRelease(image); -- if (excluded_image) -- CFRelease(excluded_image); -- return false; -- } -- -- // Request access to the raw pixel data via the image's DataProvider. -- CGDataProviderRef provider = CGImageGetDataProvider(image); -- CFDataRef data = CGDataProviderCopyData(provider); -- assert(data); -- -- const uint8_t* display_base_address = CFDataGetBytePtr(data); -- int src_bytes_per_row = CGImageGetBytesPerRow(image); -- -- // |image| size may be different from display_bounds in case the screen was -- // resized recently. -- copy_region.IntersectWith( -- DesktopRect::MakeWH(CGImageGetWidth(image), CGImageGetHeight(image))); -- -- // Copy the dirty region from the display buffer into our desktop buffer. -- uint8_t* out_ptr = frame.GetFrameDataAtPos(display_bounds.top_left()); -- for (DesktopRegion::Iterator i(copy_region); !i.IsAtEnd(); i.Advance()) { -- CopyRect(display_base_address, src_bytes_per_row, out_ptr, frame.stride(), -- DesktopFrame::kBytesPerPixel, i.rect()); -- } -- -- CFRelease(data); -- CFRelease(image); -- -- if (excluded_image) { -- CGDataProviderRef provider = CGImageGetDataProvider(excluded_image); -- CFDataRef excluded_image_data = CGDataProviderCopyData(provider); -- assert(excluded_image_data); -- display_base_address = CFDataGetBytePtr(excluded_image_data); -- src_bytes_per_row = CGImageGetBytesPerRow(excluded_image); -- -- // Translate the bounds relative to the desktop, because |frame| data -- // starts from the desktop top-left corner. -- DesktopRect window_bounds_relative_to_desktop(excluded_window_bounds); -- window_bounds_relative_to_desktop.Translate(-screen_pixel_bounds_.left(), -- -screen_pixel_bounds_.top()); -- -- DesktopRect rect_to_copy = -- DesktopRect::MakeSize(excluded_window_bounds.size()); -- rect_to_copy.IntersectWith(DesktopRect::MakeWH( -- CGImageGetWidth(excluded_image), CGImageGetHeight(excluded_image))); -- -- if (CGImageGetBitsPerPixel(excluded_image) / 8 == -- DesktopFrame::kBytesPerPixel) { -- CopyRect(display_base_address, src_bytes_per_row, -- frame.GetFrameDataAtPos( -- window_bounds_relative_to_desktop.top_left()), -- frame.stride(), DesktopFrame::kBytesPerPixel, rect_to_copy); -- } -- -- CFRelease(excluded_image_data); -- CFRelease(excluded_image); -- } -- } -- if (window_list) -- CFRelease(window_list); -- return true; --} -- --void ScreenCapturerMac::ScreenConfigurationChanged() { -- if (current_display_) { -- const MacDisplayConfiguration* config = -- desktop_config_.FindDisplayConfigurationById(current_display_); -- screen_pixel_bounds_ = config ? config->pixel_bounds : DesktopRect(); -- dip_to_pixel_scale_ = config ? config->dip_to_pixel_scale : 1.0f; -- } else { -- screen_pixel_bounds_ = desktop_config_.pixel_bounds; -- dip_to_pixel_scale_ = desktop_config_.dip_to_pixel_scale; -- } -- -- // Release existing buffers, which will be of the wrong size. -- ReleaseBuffers(); -- -- // Clear the dirty region, in case the display is down-sizing. -- helper_.ClearInvalidRegion(); -- -- // Re-mark the entire desktop as dirty. -- helper_.InvalidateScreen(screen_pixel_bounds_.size()); -- -- // Make sure the frame buffers will be reallocated. -- queue_.Reset(); --} -- --bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { -- desktop_config_ = desktop_config_monitor_->desktop_configuration(); -- for (const auto& config : desktop_config_.displays) { -- size_t pixel_width = config.pixel_bounds.width(); -- size_t pixel_height = config.pixel_bounds.height(); -- if (pixel_width == 0 || pixel_height == 0) -- continue; -- // Using a local variable forces the block to capture the raw pointer. -- DisplayStreamManager* manager = display_stream_manager_; -- int unique_id = manager->GetUniqueId(); -- CGDirectDisplayID display_id = config.id; -- DesktopVector display_origin = config.pixel_bounds.top_left(); -- -- CGDisplayStreamFrameAvailableHandler handler = -- ^(CGDisplayStreamFrameStatus status, uint64_t display_time, -- IOSurfaceRef frame_surface, CGDisplayStreamUpdateRef updateRef) { -- if (status == kCGDisplayStreamFrameStatusStopped) { -- manager->DestroyStream(unique_id); -- return; -- } -- -- if (manager->ShouldIgnoreUpdates()) -- return; -- -- // Only pay attention to frame updates. -- if (status != kCGDisplayStreamFrameStatusFrameComplete) -- return; -- -- size_t count = 0; -- const CGRect* rects = CGDisplayStreamUpdateGetRects( -- updateRef, kCGDisplayStreamUpdateDirtyRects, &count); -- if (count != 0) { -- // According to CGDisplayStream.h, it's safe to call -- // CGDisplayStreamStop() from within the callback. -- ScreenRefresh(count, rects, display_origin); -- } -- }; -- CGDisplayStreamRef display_stream = CGDisplayStreamCreate( -- display_id, pixel_width, pixel_height, 'BGRA', nullptr, handler); -- -- if (display_stream) { -- CGError error = CGDisplayStreamStart(display_stream); -- if (error != kCGErrorSuccess) -- return false; -- -- CFRunLoopSourceRef source = -- CGDisplayStreamGetRunLoopSource(display_stream); -- CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); -- display_stream_manager_->SaveStream(unique_id, display_stream); -- } -- } -- -- return true; --} -- --void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { -- display_stream_manager_->UnregisterActiveStreams(); --} -- --void ScreenCapturerMac::ScreenRefresh(CGRectCount count, -- const CGRect* rect_array, -- DesktopVector display_origin) { -- if (screen_pixel_bounds_.is_empty()) -- ScreenConfigurationChanged(); -- -- // The refresh rects are in display coordinates. We want to translate to -- // framebuffer coordinates. If a specific display is being captured, then no -- // change is necessary. If all displays are being captured, then we want to -- // translate by the origin of the display. -- DesktopVector translate_vector; -- if (!current_display_) -- translate_vector = display_origin; -- -- DesktopRegion region; -- for (CGRectCount i = 0; i < count; ++i) { -- // All rects are already in physical pixel coordinates. -- DesktopRect rect = DesktopRect::MakeXYWH( -- rect_array[i].origin.x, rect_array[i].origin.y, -- rect_array[i].size.width, rect_array[i].size.height); -- -- rect.Translate(translate_vector); -- -- region.AddRect(rect); -- } -- -- helper_.InvalidateRegion(region); --} -- --std::unique_ptr ScreenCapturerMac::CreateFrame() { -- std::unique_ptr frame( -- new BasicDesktopFrame(screen_pixel_bounds_.size())); -- frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, -- kStandardDPI * dip_to_pixel_scale_)); -- return frame; --} -- --} // namespace -- --// static --std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( -- const DesktopCaptureOptions& options) { -- if (!options.configuration_monitor()) -- return nullptr; -- -- std::unique_ptr capturer(new ScreenCapturerMac( -- options.configuration_monitor(), options.detect_updated_region())); -- if (!capturer.get()->Init()) { -- return nullptr; -- } -- -- return capturer; --} -- --} // namespace webrtc +diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn +index f675143451..65468cecd7 100644 +--- a/modules/video_capture/BUILD.gn ++++ b/modules/video_capture/BUILD.gn +@@ -100,6 +100,10 @@ if (!build_with_chromium || is_linux || is_chromeos) { + "../../media:rtc_media_base", + "../portal", + ] ++ if (build_with_mozilla) { ++ configs -= [ "../portal:pipewire_base" ] ++ public_deps = [ "//third_party/pipewire" ] ++ } + } + } + if (is_win) { +diff --git a/modules/video_capture/linux/device_info_pipewire.cc b/modules/video_capture/linux/device_info_pipewire.cc +index 1dee78f5ee..2cb6161514 100644 +--- a/modules/video_capture/linux/device_info_pipewire.cc ++++ b/modules/video_capture/linux/device_info_pipewire.cc +@@ -47,7 +47,8 @@ int32_t DeviceInfoPipeWire::GetDeviceName(uint32_t deviceNumber, + char* deviceUniqueIdUTF8, + uint32_t deviceUniqueIdUTF8Length, + char* productUniqueIdUTF8, +- uint32_t productUniqueIdUTF8Length) { ++ uint32_t productUniqueIdUTF8Length, ++ pid_t* pid) { + if (deviceNumber >= NumberOfDevices()) + return -1; + +diff --git a/modules/video_capture/linux/device_info_pipewire.h b/modules/video_capture/linux/device_info_pipewire.h +index a006c85d1b..724717be5e 100644 +--- a/modules/video_capture/linux/device_info_pipewire.h ++++ b/modules/video_capture/linux/device_info_pipewire.h +@@ -29,7 +29,8 @@ class DeviceInfoPipeWire : public DeviceInfoImpl { + char* deviceUniqueIdUTF8, + uint32_t deviceUniqueIdUTF8Length, + char* productUniqueIdUTF8 = nullptr, +- uint32_t productUniqueIdUTF8Length = 0) override; ++ uint32_t productUniqueIdUTF8Length = 0, ++ pid_t* pid = 0) override; + /* + * Fills the membervariable _captureCapabilities with capabilites for the + * given device name. -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0104.patch b/third_party/libwebrtc/moz-patch-stack/0104.patch index 353e57b16419f..d41d3d87d16cf 100644 --- a/third_party/libwebrtc/moz-patch-stack/0104.patch +++ b/third_party/libwebrtc/moz-patch-stack/0104.patch @@ -1,160 +1,732 @@ -From: Andreas Pehrson -Date: Tue, 23 May 2023 06:14:00 +0000 -Subject: Bug 1832751 - cherry-pick upstream libwebrtc commit 301e546a68. - r=webrtc-reviewers,mjf +From: Jan Grulich +Date: Thu, 15 Jun 2023 12:41:00 +0000 +Subject: Bug 1724900: WebRTC backport: PipeWire video capture: split portal + and PipeWire implementations r=pehrsons,webrtc-reviewers -Upstream commit: https://webrtc.googlesource.com/src/+/301e546a689020320f919a660591759e993ef051 - Remove SequenceCheckerImpl::valid_system_queue_ +This is a simple backport of an WebRTC upstream change. - As pointed out in issue webrtc:15146 this Mac/iOS specific variable, - makes the SequenceChecker behave incorrectly on those platforms. +Upstream commit: 56d126074e5fb62a65e4e14cce44466ce7297770 - The variable was introduced in a CL that merged the previous checker - classes, ThreadChecker and SequencedTaskChecker, but curiously neither - one of them had such a variable. So I'm not exactly sure what problem - was being solved. Hence I'm wondering if we actually need it. - - Reference: https://webrtc-review.googlesource.com/c/src/+/129721 - - Bug: webrtc:15146 - Change-Id: Ia7a9eb17b993c4f8a1e8204c658bf0b3dbdaa1e0 - Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/304401 - Reviewed-by: Peter Hanspers - Commit-Queue: Tomas Gunnarsson - Cr-Commit-Position: refs/heads/main@{#40019} - -Differential Revision: https://phabricator.services.mozilla.com/D177875 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/220fde5226ae38aa03a625b6a472b6e6ef6b6054 +Differential Revision: https://phabricator.services.mozilla.com/D178937 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0472c2c907759c916999889e8d7ce3f3ad3e7e42 --- - api/sequence_checker_unittest.cc | 13 +++++++ - .../sequence_checker_internal.cc | 37 +++---------------- - .../sequence_checker_internal.h | 1 - - 3 files changed, 18 insertions(+), 33 deletions(-) + modules/video_capture/BUILD.gn | 2 + + modules/video_capture/linux/camera_portal.cc | 242 ++++++++++++++++++ + modules/video_capture/linux/camera_portal.h | 47 ++++ + .../video_capture/linux/pipewire_session.cc | 200 +++------------ + .../video_capture/linux/pipewire_session.h | 48 ++-- + .../video_capture/video_capture_options.cc | 2 +- + modules/video_capture/video_capture_options.h | 5 +- + 7 files changed, 342 insertions(+), 204 deletions(-) + create mode 100644 modules/video_capture/linux/camera_portal.cc + create mode 100644 modules/video_capture/linux/camera_portal.h -diff --git a/api/sequence_checker_unittest.cc b/api/sequence_checker_unittest.cc -index 3efb5c78ee..f117926d73 100644 ---- a/api/sequence_checker_unittest.cc -+++ b/api/sequence_checker_unittest.cc -@@ -98,6 +98,19 @@ TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentThreadInDebug) { - [&] { EXPECT_EQ(sequence_checker.IsCurrent(), !RTC_DCHECK_IS_ON); }); - } +diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn +index 65468cecd7..1e32e87fa8 100644 +--- a/modules/video_capture/BUILD.gn ++++ b/modules/video_capture/BUILD.gn +@@ -82,6 +82,8 @@ if (!build_with_chromium || is_linux || is_chromeos) { -+#if RTC_DCHECK_IS_ON -+TEST(SequenceCheckerTest, OnlyCurrentOnOneThread) { -+ SequenceChecker sequence_checker(SequenceChecker::kDetached); -+ RunOnDifferentThread([&] { -+ EXPECT_TRUE(sequence_checker.IsCurrent()); -+ // Spawn a new thread from within the first one to guarantee that we have -+ // two concurrently active threads (and that there's no chance of the -+ // thread ref being reused). -+ RunOnDifferentThread([&] { EXPECT_FALSE(sequence_checker.IsCurrent()); }); -+ }); + if (rtc_use_pipewire) { + sources += [ ++ "linux/camera_portal.cc", ++ "linux/camera_portal.h", + "linux/device_info_pipewire.cc", + "linux/device_info_pipewire.h", + "linux/pipewire_session.cc", +diff --git a/modules/video_capture/linux/camera_portal.cc b/modules/video_capture/linux/camera_portal.cc +new file mode 100644 +index 0000000000..d217dc7251 +--- /dev/null ++++ b/modules/video_capture/linux/camera_portal.cc +@@ -0,0 +1,242 @@ ++/* ++ * Copyright (c) 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 "modules/video_capture/linux/camera_portal.h" ++ ++#include ++#include ++ ++#include "modules/portal/xdg_desktop_portal_utils.h" ++ ++namespace webrtc { ++ ++using xdg_portal::RequestResponse; ++using xdg_portal::RequestResponseFromPortalResponse; ++using xdg_portal::RequestSessionProxy; ++ ++constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; ++ ++class CameraPortalPrivate { ++ public: ++ explicit CameraPortalPrivate(CameraPortal::PortalNotifier* notifier); ++ ~CameraPortalPrivate(); ++ ++ void Start(); ++ ++ private: ++ void OnPortalDone(xdg_portal::RequestResponse result, int fd = -1); ++ ++ static void OnProxyRequested(GObject* object, ++ GAsyncResult* result, ++ gpointer user_data); ++ void ProxyRequested(GDBusProxy* proxy); ++ ++ static void OnAccessResponse(GDBusProxy* proxy, ++ GAsyncResult* result, ++ gpointer user_data); ++ static void OnResponseSignalEmitted(GDBusConnection* connection, ++ const char* sender_name, ++ const char* object_path, ++ const char* interface_name, ++ const char* signal_name, ++ GVariant* parameters, ++ gpointer user_data); ++ static void OnOpenResponse(GDBusProxy* proxy, ++ GAsyncResult* result, ++ gpointer user_data); ++ ++ CameraPortal::PortalNotifier* notifier_ = nullptr; ++ ++ GDBusConnection* connection_ = nullptr; ++ GDBusProxy* proxy_ = nullptr; ++ GCancellable* cancellable_ = nullptr; ++ guint access_request_signal_id_ = 0; ++}; ++ ++CameraPortalPrivate::CameraPortalPrivate(CameraPortal::PortalNotifier* notifier) ++ : notifier_(notifier) {} ++ ++CameraPortalPrivate::~CameraPortalPrivate() { ++ if (access_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(connection_, ++ access_request_signal_id_); ++ access_request_signal_id_ = 0; ++ } ++ if (cancellable_) { ++ g_cancellable_cancel(cancellable_); ++ g_object_unref(cancellable_); ++ cancellable_ = nullptr; ++ } ++ if (proxy_) { ++ g_object_unref(proxy_); ++ proxy_ = nullptr; ++ connection_ = nullptr; ++ } ++} ++ ++void CameraPortalPrivate::Start() { ++ cancellable_ = g_cancellable_new(); ++ Scoped error; ++ RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, ++ this); ++} ++ ++// static ++void CameraPortalPrivate::OnProxyRequested(GObject* gobject, ++ GAsyncResult* result, ++ gpointer user_data) { ++ CameraPortalPrivate* that = static_cast(user_data); ++ Scoped error; ++ GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); ++ if (!proxy) { ++ // Ignore the error caused by user cancelling the request via `cancellable_` ++ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ return; ++ RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " ++ << error->message; ++ that->OnPortalDone(RequestResponse::kError); ++ return; ++ } ++ ++ RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; ++ that->ProxyRequested(proxy); ++} ++ ++void CameraPortalPrivate::ProxyRequested(GDBusProxy* proxy) { ++ GVariantBuilder builder; ++ Scoped variant_string; ++ std::string access_handle; ++ ++ proxy_ = proxy; ++ connection_ = g_dbus_proxy_get_connection(proxy); ++ ++ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); ++ variant_string = ++ g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); ++ g_variant_builder_add(&builder, "{sv}", "handle_token", ++ g_variant_new_string(variant_string.get())); ++ ++ access_handle = ++ xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); ++ access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( ++ access_handle.c_str(), OnResponseSignalEmitted, this, connection_); ++ ++ RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; ++ g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), ++ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, ++ reinterpret_cast(OnAccessResponse), ++ this); ++} ++ ++// static ++void CameraPortalPrivate::OnAccessResponse(GDBusProxy* proxy, ++ GAsyncResult* result, ++ gpointer user_data) { ++ CameraPortalPrivate* that = static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ Scoped error; ++ Scoped variant( ++ g_dbus_proxy_call_finish(proxy, result, error.receive())); ++ if (!variant) { ++ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ return; ++ RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; ++ if (that->access_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(that->connection_, ++ that->access_request_signal_id_); ++ that->access_request_signal_id_ = 0; ++ } ++ that->OnPortalDone(RequestResponse::kError); ++ } ++} ++ ++// static ++void CameraPortalPrivate::OnResponseSignalEmitted(GDBusConnection* connection, ++ const char* sender_name, ++ const char* object_path, ++ const char* interface_name, ++ const char* signal_name, ++ GVariant* parameters, ++ gpointer user_data) { ++ CameraPortalPrivate* that = static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ uint32_t portal_response; ++ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); ++ if (portal_response) { ++ RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; ++ that->OnPortalDone(RequestResponseFromPortalResponse(portal_response)); ++ return; ++ } ++ ++ RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; ++ ++ GVariantBuilder builder; ++ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); ++ ++ g_dbus_proxy_call( ++ that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), ++ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, ++ reinterpret_cast(OnOpenResponse), that); ++} ++ ++void CameraPortalPrivate::OnOpenResponse(GDBusProxy* proxy, ++ GAsyncResult* result, ++ gpointer user_data) { ++ CameraPortalPrivate* that = static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ Scoped error; ++ Scoped outlist; ++ Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( ++ proxy, outlist.receive(), result, error.receive())); ++ if (!variant) { ++ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ return; ++ RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; ++ if (that->access_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(that->connection_, ++ that->access_request_signal_id_); ++ that->access_request_signal_id_ = 0; ++ } ++ that->OnPortalDone(RequestResponse::kError); ++ return; ++ } ++ ++ int32_t index; ++ g_variant_get(variant.get(), "(h)", &index); ++ ++ int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); ++ ++ if (fd == -1) { ++ RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " ++ << error->message; ++ that->OnPortalDone(RequestResponse::kError); ++ return; ++ } ++ ++ that->OnPortalDone(RequestResponse::kSuccess, fd); ++} ++ ++void CameraPortalPrivate::OnPortalDone(RequestResponse result, int fd) { ++ notifier_->OnCameraRequestResult(result, fd); ++} ++ ++CameraPortal::CameraPortal(PortalNotifier* notifier) ++ : private_(std::make_unique(notifier)) {} ++ ++CameraPortal::~CameraPortal() {} ++ ++void CameraPortal::Start() { ++ private_->Start(); +} -+#endif + - TEST(SequenceCheckerTest, MethodNotAllowedOnDifferentTaskQueueInDebug) { - SequenceChecker sequence_checker; - TaskQueueForTest queue; -diff --git a/rtc_base/synchronization/sequence_checker_internal.cc b/rtc_base/synchronization/sequence_checker_internal.cc -index 9831f07d7d..3e205b91d5 100644 ---- a/rtc_base/synchronization/sequence_checker_internal.cc -+++ b/rtc_base/synchronization/sequence_checker_internal.cc -@@ -11,52 +11,30 @@ ++} // namespace webrtc +diff --git a/modules/video_capture/linux/camera_portal.h b/modules/video_capture/linux/camera_portal.h +new file mode 100644 +index 0000000000..36f2ec8b8a +--- /dev/null ++++ b/modules/video_capture/linux/camera_portal.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 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 MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ ++#define MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ ++ ++#include ++#include ++ ++#include "modules/portal/portal_request_response.h" ++#include "rtc_base/system/rtc_export.h" ++ ++namespace webrtc { ++ ++class CameraPortalPrivate; ++ ++class RTC_EXPORT CameraPortal { ++ public: ++ class PortalNotifier { ++ public: ++ virtual void OnCameraRequestResult(xdg_portal::RequestResponse result, ++ int fd) = 0; ++ ++ protected: ++ PortalNotifier() = default; ++ virtual ~PortalNotifier() = default; ++ }; ++ ++ explicit CameraPortal(PortalNotifier* notifier); ++ ~CameraPortal(); ++ ++ void Start(); ++ ++ private: ++ std::unique_ptr private_; ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ +diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc +index 14d557d6c1..f2680b2816 100644 +--- a/modules/video_capture/linux/pipewire_session.cc ++++ b/modules/video_capture/linux/pipewire_session.cc +@@ -10,7 +10,6 @@ - #include + #include "modules/video_capture/linux/pipewire_session.h" --#if defined(WEBRTC_MAC) --#include --#endif -- - #include "rtc_base/checks.h" - #include "rtc_base/strings/string_builder.h" +-#include + #include + #include + #include +@@ -19,18 +18,14 @@ + + #include "common_video/libyuv/include/webrtc_libyuv.h" + #include "modules/portal/pipewire_utils.h" +-#include "modules/portal/xdg_desktop_portal_utils.h" + #include "modules/video_capture/device_info_impl.h" ++#include "rtc_base/logging.h" + #include "rtc_base/string_encode.h" + #include "rtc_base/string_to_number.h" namespace webrtc { - namespace webrtc_sequence_checker_internal { --namespace { --// On Mac, returns the label of the current dispatch queue; elsewhere, return --// null. --const void* GetSystemQueueRef() { --#if defined(WEBRTC_MAC) -- return dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL); --#else -- return nullptr; --#endif + namespace videocapturemodule { + +-using xdg_portal::RequestSessionProxy; +- +-constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; +- + VideoType PipeWireRawFormatToVideoType(uint32_t id) { + switch (id) { + case SPA_VIDEO_FORMAT_I420: +@@ -215,181 +210,45 @@ bool PipeWireNode::ParseFormat(const spa_pod* param, + return cap->videoType != VideoType::kUnknown; + } + +-PipeWireSession::PipeWireSession() +- : status_(VideoCaptureOptions::Status::UNINITIALIZED) {} +- +-PipeWireSession::~PipeWireSession() { +- Cleanup(); +-} ++CameraPortalNotifier::CameraPortalNotifier(PipeWireSession* session) ++ : session_(session) {} + +-void PipeWireSession::Init(VideoCaptureOptions::Callback* callback) { +- callback_ = callback; +- cancellable_ = g_cancellable_new(); +- Scoped error; +- RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, +- this); -} - --} // namespace - - SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread) - : attached_(attach_to_current_thread), - valid_thread_(rtc::CurrentThreadRef()), -- valid_queue_(TaskQueueBase::Current()), -- valid_system_queue_(GetSystemQueueRef()) {} -+ valid_queue_(TaskQueueBase::Current()) {} - - bool SequenceCheckerImpl::IsCurrent() const { - const TaskQueueBase* const current_queue = TaskQueueBase::Current(); - const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); -- const void* const current_system_queue = GetSystemQueueRef(); - MutexLock scoped_lock(&lock_); - if (!attached_) { // Previously detached. - attached_ = true; - valid_thread_ = current_thread; - valid_queue_ = current_queue; -- valid_system_queue_ = current_system_queue; - return true; - } - if (valid_queue_) { - return valid_queue_ == current_queue; +-// static +-void PipeWireSession::OnProxyRequested(GObject* gobject, +- GAsyncResult* result, +- gpointer user_data) { +- PipeWireSession* that = static_cast(user_data); +- Scoped error; +- GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); +- if (!proxy) { +- // Ignore the error caused by user cancelling the request via `cancellable_` +- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) +- return; +- RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " +- << error->message; +- that->Finish(VideoCaptureOptions::Status::DENIED); +- return; ++void CameraPortalNotifier::OnCameraRequestResult( ++ xdg_portal::RequestResponse result, ++ int fd) { ++ if (result == xdg_portal::RequestResponse::kSuccess) { ++ session_->InitPipeWire(fd); ++ } else if (result == xdg_portal::RequestResponse::kUserCancelled) { ++ session_->Finish(VideoCaptureOptions::Status::DENIED); ++ } else { ++ session_->Finish(VideoCaptureOptions::Status::ERROR); } -- if (valid_system_queue_ && valid_system_queue_ == current_system_queue) { -- return true; +- +- RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; +- that->ProxyRequested(proxy); + } + +-void PipeWireSession::ProxyRequested(GDBusProxy* proxy) { +- GVariantBuilder builder; +- Scoped variant_string; +- std::string access_handle; +- +- proxy_ = proxy; +- connection_ = g_dbus_proxy_get_connection(proxy); +- +- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); +- variant_string = +- g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); +- g_variant_builder_add(&builder, "{sv}", "handle_token", +- g_variant_new_string(variant_string.get())); +- +- access_handle = +- xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); +- access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( +- access_handle.c_str(), OnResponseSignalEmitted, this, connection_); +- +- RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; +- g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), +- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, +- reinterpret_cast(OnAccessResponse), +- this); +-} ++PipeWireSession::PipeWireSession() {} + +-// static +-void PipeWireSession::OnAccessResponse(GDBusProxy* proxy, +- GAsyncResult* result, +- gpointer user_data) { +- PipeWireSession* that = static_cast(user_data); +- RTC_DCHECK(that); +- +- Scoped error; +- Scoped variant( +- g_dbus_proxy_call_finish(proxy, result, error.receive())); +- if (!variant) { +- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) +- return; +- RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; +- if (that->access_request_signal_id_) { +- g_dbus_connection_signal_unsubscribe(that->connection_, +- that->access_request_signal_id_); +- that->access_request_signal_id_ = 0; +- } +- that->Finish(VideoCaptureOptions::Status::ERROR); - } - return rtc::IsThreadRefEqual(valid_thread_, current_thread); +-} +- +-// static +-void PipeWireSession::OnResponseSignalEmitted(GDBusConnection* connection, +- const char* sender_name, +- const char* object_path, +- const char* interface_name, +- const char* signal_name, +- GVariant* parameters, +- gpointer user_data) { +- PipeWireSession* that = static_cast(user_data); +- RTC_DCHECK(that); +- +- uint32_t portal_response; +- g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); +- if (portal_response) { +- RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; +- that->Finish(VideoCaptureOptions::Status::DENIED); +- return; +- } +- +- RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; +- +- GVariantBuilder builder; +- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); +- +- g_dbus_proxy_call( +- that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), +- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, +- reinterpret_cast(OnOpenResponse), that); ++PipeWireSession::~PipeWireSession() { ++ Cleanup(); } -@@ -71,7 +49,6 @@ void SequenceCheckerImpl::Detach() { - std::string SequenceCheckerImpl::ExpectationToString() const { - const TaskQueueBase* const current_queue = TaskQueueBase::Current(); - const rtc::PlatformThreadRef current_thread = rtc::CurrentThreadRef(); -- const void* const current_system_queue = GetSystemQueueRef(); - MutexLock scoped_lock(&lock_); - if (!attached_) - return "Checker currently not attached."; -@@ -85,17 +62,13 @@ std::string SequenceCheckerImpl::ExpectationToString() const { - - rtc::StringBuilder message; - message.AppendFormat( -- "# Expected: TQ: %p SysQ: %p Thread: %p\n" -- "# Actual: TQ: %p SysQ: %p Thread: %p\n", -- valid_queue_, valid_system_queue_, -- reinterpret_cast(valid_thread_), current_queue, -- current_system_queue, reinterpret_cast(current_thread)); -+ "# Expected: TQ: %p Thread: %p\n" -+ "# Actual: TQ: %p Thread: %p\n", -+ valid_queue_, reinterpret_cast(valid_thread_), current_queue, -+ reinterpret_cast(current_thread)); - - if ((valid_queue_ || current_queue) && valid_queue_ != current_queue) { - message << "TaskQueue doesn't match\n"; -- } else if (valid_system_queue_ && -- valid_system_queue_ != current_system_queue) { -- message << "System queue doesn't match\n"; - } else if (!rtc::IsThreadRefEqual(valid_thread_, current_thread)) { - message << "Threads don't match\n"; +-void PipeWireSession::OnOpenResponse(GDBusProxy* proxy, +- GAsyncResult* result, +- gpointer user_data) { +- PipeWireSession* that = static_cast(user_data); +- RTC_DCHECK(that); +- +- Scoped error; +- Scoped outlist; +- Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( +- proxy, outlist.receive(), result, error.receive())); +- if (!variant) { +- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) +- return; +- RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; +- if (that->access_request_signal_id_) { +- g_dbus_connection_signal_unsubscribe(that->connection_, +- that->access_request_signal_id_); +- that->access_request_signal_id_ = 0; +- } +- that->Finish(VideoCaptureOptions::Status::ERROR); +- return; +- } +- +- int32_t index; +- g_variant_get(variant.get(), "(h)", &index); +- +- int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); +- +- if (fd == -1) { +- RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " +- << error->message; +- that->Finish(VideoCaptureOptions::Status::ERROR); +- return; +- } ++void PipeWireSession::Init(VideoCaptureOptions::Callback* callback, int fd) { ++ callback_ = callback; + +- if (!InitializePipeWire()) { +- that->Finish(VideoCaptureOptions::Status::UNAVAILABLE); +- return; ++ if (fd != -1) { ++ InitPipeWire(fd); ++ } else { ++ portal_notifier_ = std::make_unique(this); ++ portal_ = std::make_unique(portal_notifier_.get()); ++ portal_->Start(); } -diff --git a/rtc_base/synchronization/sequence_checker_internal.h b/rtc_base/synchronization/sequence_checker_internal.h -index a66e9ee8ec..22503027a5 100644 ---- a/rtc_base/synchronization/sequence_checker_internal.h -+++ b/rtc_base/synchronization/sequence_checker_internal.h -@@ -50,7 +50,6 @@ class RTC_EXPORT SequenceCheckerImpl { - mutable bool attached_ RTC_GUARDED_BY(lock_); - mutable rtc::PlatformThreadRef valid_thread_ RTC_GUARDED_BY(lock_); - mutable const TaskQueueBase* valid_queue_ RTC_GUARDED_BY(lock_); -- mutable const void* valid_system_queue_ RTC_GUARDED_BY(lock_); +- +- if (!that->StartPipeWire(fd)) +- that->Finish(VideoCaptureOptions::Status::ERROR); + } + +-void PipeWireSession::StopDBus() { +- if (access_request_signal_id_) { +- g_dbus_connection_signal_unsubscribe(connection_, +- access_request_signal_id_); +- access_request_signal_id_ = 0; +- } +- if (cancellable_) { +- g_cancellable_cancel(cancellable_); +- g_object_unref(cancellable_); +- cancellable_ = nullptr; +- } +- if (proxy_) { +- g_object_unref(proxy_); +- proxy_ = nullptr; +- connection_ = nullptr; +- } ++void PipeWireSession::InitPipeWire(int fd) { ++ if (!InitializePipeWire()) ++ Finish(VideoCaptureOptions::Status::UNAVAILABLE); ++ ++ if (!StartPipeWire(fd)) ++ Finish(VideoCaptureOptions::Status::ERROR); + } + + bool PipeWireSession::StartPipeWire(int fd) { +@@ -523,7 +382,6 @@ void PipeWireSession::Finish(VideoCaptureOptions::Status status) { + + void PipeWireSession::Cleanup() { + StopPipeWire(); +- StopDBus(); + } + + } // namespace videocapturemodule +diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h +index 71cd1fed8b..7055e50fae 100644 +--- a/modules/video_capture/linux/pipewire_session.h ++++ b/modules/video_capture/linux/pipewire_session.h +@@ -11,7 +11,6 @@ + #ifndef MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ + #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ + +-#include + #include + #include + +@@ -21,6 +20,7 @@ + + #include "api/ref_counted_base.h" + #include "api/scoped_refptr.h" ++#include "modules/video_capture/linux/camera_portal.h" + #include "modules/video_capture/video_capture.h" + #include "modules/video_capture/video_capture_options.h" + +@@ -66,40 +66,33 @@ class PipeWireNode { + std::vector capabilities_; + }; + ++class CameraPortalNotifier : public CameraPortal::PortalNotifier { ++ public: ++ CameraPortalNotifier(PipeWireSession* session); ++ ~CameraPortalNotifier() = default; ++ ++ void OnCameraRequestResult(xdg_portal::RequestResponse result, ++ int fd) override; ++ ++ private: ++ PipeWireSession* session_; ++}; ++ + class PipeWireSession : public rtc::RefCountedNonVirtual { + public: + PipeWireSession(); + ~PipeWireSession(); + +- void Init(VideoCaptureOptions::Callback* callback); +- void CancelInit(); ++ void Init(VideoCaptureOptions::Callback* callback, int fd = -1); + + const std::deque& nodes() const { return nodes_; } + ++ friend class CameraPortalNotifier; + friend class PipeWireNode; + friend class VideoCaptureModulePipeWire; + + private: +- static void OnProxyRequested(GObject* object, +- GAsyncResult* result, +- gpointer user_data); +- void ProxyRequested(GDBusProxy* proxy); +- +- static void OnAccessResponse(GDBusProxy* proxy, +- GAsyncResult* result, +- gpointer user_data); +- static void OnResponseSignalEmitted(GDBusConnection* connection, +- const char* sender_name, +- const char* object_path, +- const char* interface_name, +- const char* signal_name, +- GVariant* parameters, +- gpointer user_data); +- static void OnOpenResponse(GDBusProxy* proxy, +- GAsyncResult* result, +- gpointer user_data); +- void StopDBus(); +- ++ void InitPipeWire(int fd); + bool StartPipeWire(int fd); + void StopPipeWire(); + void PipeWireSync(); +@@ -124,13 +117,6 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { + + VideoCaptureOptions::Callback* callback_ = nullptr; + +- GDBusConnection* connection_ = nullptr; +- GDBusProxy* proxy_ = nullptr; +- GCancellable* cancellable_ = nullptr; +- guint access_request_signal_id_ = 0; +- +- VideoCaptureOptions::Status status_; +- + struct pw_thread_loop* pw_main_loop_ = nullptr; + struct pw_context* pw_context_ = nullptr; + struct pw_core* pw_core_ = nullptr; +@@ -142,6 +128,8 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { + int sync_seq_ = 0; + + std::deque nodes_; ++ std::unique_ptr portal_; ++ std::unique_ptr portal_notifier_; }; - // Do nothing implementation, for use in release mode. + } // namespace videocapturemodule +diff --git a/modules/video_capture/video_capture_options.cc b/modules/video_capture/video_capture_options.cc +index 444c23fcbc..203d0a604b 100644 +--- a/modules/video_capture/video_capture_options.cc ++++ b/modules/video_capture/video_capture_options.cc +@@ -33,7 +33,7 @@ void VideoCaptureOptions::Init(Callback* callback) { + if (allow_pipewire_) { + pipewire_session_ = + rtc::make_ref_counted(); +- pipewire_session_->Init(callback); ++ pipewire_session_->Init(callback, pipewire_fd_); + return; + } + #endif +diff --git a/modules/video_capture/video_capture_options.h b/modules/video_capture/video_capture_options.h +index f35c6142b6..c90e035f37 100644 +--- a/modules/video_capture/video_capture_options.h ++++ b/modules/video_capture/video_capture_options.h +@@ -21,8 +21,7 @@ class PipeWireSession; + } + #endif + +-// An object that stores initialization parameters for screen and window +-// capturers. ++// An object that stores initialization parameters for video capturers + class RTC_EXPORT VideoCaptureOptions { + public: + VideoCaptureOptions(); +@@ -60,6 +59,7 @@ class RTC_EXPORT VideoCaptureOptions { + #if defined(WEBRTC_USE_PIPEWIRE) + bool allow_pipewire() const { return allow_pipewire_; } + void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } ++ void set_pipewire_fd(int fd) { pipewire_fd_ = fd; } + rtc::scoped_refptr pipewire_session(); + #endif + +@@ -69,6 +69,7 @@ class RTC_EXPORT VideoCaptureOptions { + #endif + #if defined(WEBRTC_USE_PIPEWIRE) + bool allow_pipewire_ = false; ++ int pipewire_fd_ = -1; + rtc::scoped_refptr pipewire_session_; + #endif + }; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0105.patch b/third_party/libwebrtc/moz-patch-stack/0105.patch index 4769543fc8fc1..0257ae50c9b8c 100644 --- a/third_party/libwebrtc/moz-patch-stack/0105.patch +++ b/third_party/libwebrtc/moz-patch-stack/0105.patch @@ -1,66 +1,32 @@ -From: Andreas Pehrson -Date: Tue, 23 May 2023 06:14:00 +0000 -Subject: Bug 1809672 - Refactor TabCapturerWebrtc creation. - r=ng,webrtc-reviewers +From: Jan-Ivar Bruaroey +Date: Wed, 28 Jun 2023 20:45:00 -0400 +Subject: Bug 1839451 - (fix-0f43da2248) Keep mozilla's + RTCPReceiver::RemoteRTCPSenderInfo function working. -This restores libwebrtc's DesktopCapturer to their upstream state as far as -the tab capturer is concerned. - -Differential Revision: https://phabricator.services.mozilla.com/D174290 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/3778b2a0e3f93a2077303b91739cdd2eeb590726 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/154c9cdb386d0f50c5e1549270e1af6ab4969602 --- - modules/desktop_capture/desktop_capturer.cc | 11 ----------- - modules/desktop_capture/desktop_capturer.h | 8 -------- - 2 files changed, 19 deletions(-) + modules/rtp_rtcp/source/rtcp_receiver.cc | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) -diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc -index 1af19a1fd2..7f601821fc 100644 ---- a/modules/desktop_capture/desktop_capturer.cc -+++ b/modules/desktop_capture/desktop_capturer.cc -@@ -128,17 +128,6 @@ std::unique_ptr DesktopCapturer::CreateScreenCapturer( - return capturer; +diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc +index da653cd68a..8e178da67d 100644 +--- a/modules/rtp_rtcp/source/rtcp_receiver.cc ++++ b/modules/rtp_rtcp/source/rtcp_receiver.cc +@@ -399,10 +399,10 @@ void RTCPReceiver::RemoteRTCPSenderInfo(uint32_t* packet_count, + int64_t* ntp_timestamp_ms, + int64_t* remote_ntp_timestamp_ms) const { + MutexLock lock(&rtcp_receiver_lock_); +- *packet_count = remote_sender_packet_count_; +- *octet_count = remote_sender_octet_count_; +- *ntp_timestamp_ms = last_received_sr_ntp_.ToMs(); +- *remote_ntp_timestamp_ms = remote_sender_ntp_time_.ToMs(); ++ *packet_count = remote_sender_.packets_sent; ++ *octet_count = remote_sender_.bytes_sent; ++ *ntp_timestamp_ms = remote_sender_.last_arrival_timestamp.ToMs(); ++ *remote_ntp_timestamp_ms = remote_sender_.last_remote_timestamp.ToMs(); } --// static --std::unique_ptr DesktopCapturer::CreateTabCapturer( -- const DesktopCaptureOptions& options) { -- std::unique_ptr capturer = CreateRawTabCapturer(options); -- if (capturer && options.detect_updated_region()) { -- capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); -- } -- -- return capturer; --} -- - #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - bool DesktopCapturer::IsRunningUnderWayland() { - const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); -diff --git a/modules/desktop_capture/desktop_capturer.h b/modules/desktop_capture/desktop_capturer.h -index 64f3187f51..5efd2efc0f 100644 ---- a/modules/desktop_capture/desktop_capturer.h -+++ b/modules/desktop_capture/desktop_capturer.h -@@ -191,10 +191,6 @@ class RTC_EXPORT DesktopCapturer { - static std::unique_ptr CreateScreenCapturer( - const DesktopCaptureOptions& options); - -- // Creates a DesktopCapturer instance which targets to capture tab. -- static std::unique_ptr CreateTabCapturer( -- const DesktopCaptureOptions& options); -- - #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) - static bool IsRunningUnderWayland(); - -@@ -225,10 +221,6 @@ class RTC_EXPORT DesktopCapturer { - // capture screens. - static std::unique_ptr CreateRawScreenCapturer( - const DesktopCaptureOptions& options); -- -- // Creates a DesktopCapturer instance which targets to capture tabs -- static std::unique_ptr CreateRawTabCapturer( -- const DesktopCaptureOptions& options); - }; - - } // namespace webrtc + std::vector RTCPReceiver::GetLatestReportBlockData() const { -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0106.patch b/third_party/libwebrtc/moz-patch-stack/0106.patch index 573a4f96d212c..6efdabd0a173b 100644 --- a/third_party/libwebrtc/moz-patch-stack/0106.patch +++ b/third_party/libwebrtc/moz-patch-stack/0106.patch @@ -1,58 +1,26 @@ -From: Nico Grunbaum -Date: Tue, 6 Jun 2023 16:37:00 -0700 -Subject: Bug 1833237 - (fix-f0be3bee1f) remove reference to - portal:pipewire_base;r?pehrsons +From: Jan-Ivar Bruaroey +Date: Fri, 30 Jun 2023 12:20:00 -0400 +Subject: Bug 1839451 - (fix-f6eae959bf) + s/rtc_encoder_simulcast_proxy/rtc_simulcast_encoder_adapter/ BUILD ref. -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/8ff886a4d366b4be35b329d1ef733a6df542067c +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/876b3f5821cd5c30564a82c1da7d057d79d17b01 --- - modules/video_capture/BUILD.gn | 4 ++++ - modules/video_capture/linux/device_info_pipewire.cc | 3 ++- - modules/video_capture/linux/device_info_pipewire.h | 3 ++- - 3 files changed, 8 insertions(+), 2 deletions(-) + BUILD.gn | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn -index f675143451..65468cecd7 100644 ---- a/modules/video_capture/BUILD.gn -+++ b/modules/video_capture/BUILD.gn -@@ -100,6 +100,10 @@ if (!build_with_chromium || is_linux || is_chromeos) { - "../../media:rtc_media_base", - "../portal", - ] -+ if (build_with_mozilla) { -+ configs -= [ "../portal:pipewire_base" ] -+ public_deps = [ "//third_party/pipewire" ] -+ } - } - } - if (is_win) { -diff --git a/modules/video_capture/linux/device_info_pipewire.cc b/modules/video_capture/linux/device_info_pipewire.cc -index 1dee78f5ee..2cb6161514 100644 ---- a/modules/video_capture/linux/device_info_pipewire.cc -+++ b/modules/video_capture/linux/device_info_pipewire.cc -@@ -47,7 +47,8 @@ int32_t DeviceInfoPipeWire::GetDeviceName(uint32_t deviceNumber, - char* deviceUniqueIdUTF8, - uint32_t deviceUniqueIdUTF8Length, - char* productUniqueIdUTF8, -- uint32_t productUniqueIdUTF8Length) { -+ uint32_t productUniqueIdUTF8Length, -+ pid_t* pid) { - if (deviceNumber >= NumberOfDevices()) - return -1; - -diff --git a/modules/video_capture/linux/device_info_pipewire.h b/modules/video_capture/linux/device_info_pipewire.h -index a006c85d1b..724717be5e 100644 ---- a/modules/video_capture/linux/device_info_pipewire.h -+++ b/modules/video_capture/linux/device_info_pipewire.h -@@ -29,7 +29,8 @@ class DeviceInfoPipeWire : public DeviceInfoImpl { - char* deviceUniqueIdUTF8, - uint32_t deviceUniqueIdUTF8Length, - char* productUniqueIdUTF8 = nullptr, -- uint32_t productUniqueIdUTF8Length = 0) override; -+ uint32_t productUniqueIdUTF8Length = 0, -+ pid_t* pid = 0) override; - /* - * Fills the membervariable _captureCapabilities with capabilites for the - * given device name. +diff --git a/BUILD.gn b/BUILD.gn +index 9492870751..00444cdbfa 100644 +--- a/BUILD.gn ++++ b/BUILD.gn +@@ -573,7 +573,7 @@ if (!build_with_chromium) { + deps += [ + "api/video_codecs:video_codecs_api", + "api/video_codecs:rtc_software_fallback_wrappers", +- "media:rtc_encoder_simulcast_proxy", ++ "media:rtc_simulcast_encoder_adapter", + "modules/video_coding:webrtc_vp8", + "modules/video_coding:webrtc_vp9", + ] -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0107.patch b/third_party/libwebrtc/moz-patch-stack/0107.patch index fcfb0a367f27a..47a887af50e34 100644 --- a/third_party/libwebrtc/moz-patch-stack/0107.patch +++ b/third_party/libwebrtc/moz-patch-stack/0107.patch @@ -1,42 +1,31 @@ -From: Michael Froman -Date: Fri, 9 Jun 2023 19:59:00 +0000 -Subject: Bug 1837647 - limit GetDpiForMonitor to return default value to fix - Win7 tests. r=dbaker,webrtc-reviewers +From: Jan Grulich +Date: Tue, 4 Jul 2023 08:34:00 +0000 +Subject: Bug 1839829 - WebRTC backport: PipeWire video capture - initialize + pw_stream raw pointer member r=webrtc-reviewers,ng -Upstream commit 60795e8c7a added a call to ::GetDpiForMonitor which is only -supported in Win8 and newer. This is causing perma-orange on try, so we'll -disable it for now and fix properly in Bug 1837667. +This is a simple backport of an WebRTC upstream change. -Differential Revision: https://phabricator.services.mozilla.com/D180460 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/501ade4b55d97797e4cf4416ddf1aa5aca207b9e +Upstream commit: e21745a78b430ed4f2119b6342acbaa30a52b406 + +Differential Revision: https://phabricator.services.mozilla.com/D182671 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/2174ddbbb4733a8f9b9cef34d2e6c3a1ceb244d4 --- - modules/desktop_capture/win/screen_capture_utils.cc | 6 ++++++ - 1 file changed, 6 insertions(+) + modules/video_capture/linux/video_capture_pipewire.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/modules/desktop_capture/win/screen_capture_utils.cc b/modules/desktop_capture/win/screen_capture_utils.cc -index 5409417a88..c0144b0ef3 100644 ---- a/modules/desktop_capture/win/screen_capture_utils.cc -+++ b/modules/desktop_capture/win/screen_capture_utils.cc -@@ -147,6 +147,11 @@ DesktopRect GetFullscreenRect() { - } - - DesktopVector GetDpiForMonitor(HMONITOR monitor) { -+// See Bug 1837647 - upstream commit 60795e8c7a added this method using -+// ::GetDpiForMonitor which is not available on Win7 machines. For now, -+// we'll return the default case of {96, 96} until we can properly -+// restore the functionality for newer machines (See Bug 1837667). -+#if 0 - UINT dpi_x, dpi_y; - // MDT_EFFECTIVE_DPI includes the scale factor as well as the system DPI. - HRESULT hr = ::GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); -@@ -163,6 +168,7 @@ DesktopVector GetDpiForMonitor(HMONITOR monitor) { - ReleaseDC(nullptr, hdc); - return dpi; - } -+#endif +diff --git a/modules/video_capture/linux/video_capture_pipewire.h b/modules/video_capture/linux/video_capture_pipewire.h +index e2c8d1b168..2a58c7d3e0 100644 +--- a/modules/video_capture/linux/video_capture_pipewire.h ++++ b/modules/video_capture/linux/video_capture_pipewire.h +@@ -48,7 +48,7 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl { + VideoCaptureCapability frameInfo_; + bool started_; - // If everything fails, then return the default DPI for Windows. - return {96, 96}; +- struct pw_stream* stream_; ++ struct pw_stream* stream_ = nullptr; + struct spa_hook stream_listener_; + }; + } // namespace videocapturemodule -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0108.patch b/third_party/libwebrtc/moz-patch-stack/0108.patch index 89853b94677f2..ecec7c02c6357 100644 --- a/third_party/libwebrtc/moz-patch-stack/0108.patch +++ b/third_party/libwebrtc/moz-patch-stack/0108.patch @@ -1,732 +1,36 @@ -From: Jan Grulich -Date: Thu, 15 Jun 2023 09:13:00 +0000 -Subject: Bug 1724900: WebRTC backport: PipeWire video capture: split portal - and PipeWire implementations r=pehrsons,webrtc-reviewers +From: Nico Grunbaum +Date: Thu, 22 Jun 2023 16:23:00 +0000 +Subject: Bug 1837918 - libwebrtc update broke the build on + OpenBSD;r=mjf,webrtc-reviewers -This is a simple backport of an WebRTC upstream change. - -Upstream commit: 56d126074e5fb62a65e4e14cce44466ce7297770 - -Differential Revision: https://phabricator.services.mozilla.com/D178937 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/241d7632685a0c27bff6b905461705cd1c659f3b +Differential Revision: https://phabricator.services.mozilla.com/D181791 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/2a6a838b7021bb285f9485c2ceda6ba2543e0d6f --- - modules/video_capture/BUILD.gn | 2 + - modules/video_capture/linux/camera_portal.cc | 242 ++++++++++++++++++ - modules/video_capture/linux/camera_portal.h | 47 ++++ - .../video_capture/linux/pipewire_session.cc | 200 +++------------ - .../video_capture/linux/pipewire_session.h | 48 ++-- - .../video_capture/video_capture_options.cc | 2 +- - modules/video_capture/video_capture_options.h | 5 +- - 7 files changed, 342 insertions(+), 204 deletions(-) - create mode 100644 modules/video_capture/linux/camera_portal.cc - create mode 100644 modules/video_capture/linux/camera_portal.h + modules/video_capture/video_capture_options.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn -index 65468cecd7..1e32e87fa8 100644 ---- a/modules/video_capture/BUILD.gn -+++ b/modules/video_capture/BUILD.gn -@@ -82,6 +82,8 @@ if (!build_with_chromium || is_linux || is_chromeos) { - - if (rtc_use_pipewire) { - sources += [ -+ "linux/camera_portal.cc", -+ "linux/camera_portal.h", - "linux/device_info_pipewire.cc", - "linux/device_info_pipewire.h", - "linux/pipewire_session.cc", -diff --git a/modules/video_capture/linux/camera_portal.cc b/modules/video_capture/linux/camera_portal.cc -new file mode 100644 -index 0000000000..d217dc7251 ---- /dev/null -+++ b/modules/video_capture/linux/camera_portal.cc -@@ -0,0 +1,242 @@ -+/* -+ * Copyright (c) 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 "modules/video_capture/linux/camera_portal.h" -+ -+#include -+#include -+ -+#include "modules/portal/xdg_desktop_portal_utils.h" -+ -+namespace webrtc { -+ -+using xdg_portal::RequestResponse; -+using xdg_portal::RequestResponseFromPortalResponse; -+using xdg_portal::RequestSessionProxy; -+ -+constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -+ -+class CameraPortalPrivate { -+ public: -+ explicit CameraPortalPrivate(CameraPortal::PortalNotifier* notifier); -+ ~CameraPortalPrivate(); -+ -+ void Start(); -+ -+ private: -+ void OnPortalDone(xdg_portal::RequestResponse result, int fd = -1); -+ -+ static void OnProxyRequested(GObject* object, -+ GAsyncResult* result, -+ gpointer user_data); -+ void ProxyRequested(GDBusProxy* proxy); -+ -+ static void OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ static void OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ -+ CameraPortal::PortalNotifier* notifier_ = nullptr; -+ -+ GDBusConnection* connection_ = nullptr; -+ GDBusProxy* proxy_ = nullptr; -+ GCancellable* cancellable_ = nullptr; -+ guint access_request_signal_id_ = 0; -+}; -+ -+CameraPortalPrivate::CameraPortalPrivate(CameraPortal::PortalNotifier* notifier) -+ : notifier_(notifier) {} -+ -+CameraPortalPrivate::~CameraPortalPrivate() { -+ if (access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, -+ access_request_signal_id_); -+ access_request_signal_id_ = 0; -+ } -+ if (cancellable_) { -+ g_cancellable_cancel(cancellable_); -+ g_object_unref(cancellable_); -+ cancellable_ = nullptr; -+ } -+ if (proxy_) { -+ g_object_unref(proxy_); -+ proxy_ = nullptr; -+ connection_ = nullptr; -+ } -+} -+ -+void CameraPortalPrivate::Start() { -+ cancellable_ = g_cancellable_new(); -+ Scoped error; -+ RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -+ this); -+} -+ -+// static -+void CameraPortalPrivate::OnProxyRequested(GObject* gobject, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ Scoped error; -+ GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -+ if (!proxy) { -+ // Ignore the error caused by user cancelling the request via `cancellable_` -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -+ << error->message; -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -+ that->ProxyRequested(proxy); -+} -+ -+void CameraPortalPrivate::ProxyRequested(GDBusProxy* proxy) { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ std::string access_handle; -+ -+ proxy_ = proxy; -+ connection_ = g_dbus_proxy_get_connection(proxy); -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ variant_string = -+ g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ access_handle = -+ xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -+ access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -+ access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -+ -+ RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -+ g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -+ reinterpret_cast(OnAccessResponse), -+ this); -+} -+ -+// static -+void CameraPortalPrivate::OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->OnPortalDone(RequestResponse::kError); -+ } -+} -+ -+// static -+void CameraPortalPrivate::OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ uint32_t portal_response; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -+ if (portal_response) { -+ RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -+ that->OnPortalDone(RequestResponseFromPortalResponse(portal_response)); -+ return; -+ } -+ -+ RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -+ -+ GVariantBuilder builder; -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ -+ g_dbus_proxy_call( -+ that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -+ reinterpret_cast(OnOpenResponse), that); -+} -+ -+void CameraPortalPrivate::OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped outlist; -+ Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -+ proxy, outlist.receive(), result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ int32_t index; -+ g_variant_get(variant.get(), "(h)", &index); -+ -+ int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -+ -+ if (fd == -1) { -+ RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -+ << error->message; -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ that->OnPortalDone(RequestResponse::kSuccess, fd); -+} -+ -+void CameraPortalPrivate::OnPortalDone(RequestResponse result, int fd) { -+ notifier_->OnCameraRequestResult(result, fd); -+} -+ -+CameraPortal::CameraPortal(PortalNotifier* notifier) -+ : private_(std::make_unique(notifier)) {} -+ -+CameraPortal::~CameraPortal() {} -+ -+void CameraPortal::Start() { -+ private_->Start(); -+} -+ -+} // namespace webrtc -diff --git a/modules/video_capture/linux/camera_portal.h b/modules/video_capture/linux/camera_portal.h -new file mode 100644 -index 0000000000..36f2ec8b8a ---- /dev/null -+++ b/modules/video_capture/linux/camera_portal.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (c) 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 MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -+#define MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -+ -+#include -+#include -+ -+#include "modules/portal/portal_request_response.h" -+#include "rtc_base/system/rtc_export.h" -+ -+namespace webrtc { -+ -+class CameraPortalPrivate; -+ -+class RTC_EXPORT CameraPortal { -+ public: -+ class PortalNotifier { -+ public: -+ virtual void OnCameraRequestResult(xdg_portal::RequestResponse result, -+ int fd) = 0; -+ -+ protected: -+ PortalNotifier() = default; -+ virtual ~PortalNotifier() = default; -+ }; -+ -+ explicit CameraPortal(PortalNotifier* notifier); -+ ~CameraPortal(); -+ -+ void Start(); -+ -+ private: -+ std::unique_ptr private_; -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc -index 14d557d6c1..f2680b2816 100644 ---- a/modules/video_capture/linux/pipewire_session.cc -+++ b/modules/video_capture/linux/pipewire_session.cc -@@ -10,7 +10,6 @@ - - #include "modules/video_capture/linux/pipewire_session.h" - --#include - #include - #include - #include -@@ -19,18 +18,14 @@ - - #include "common_video/libyuv/include/webrtc_libyuv.h" - #include "modules/portal/pipewire_utils.h" --#include "modules/portal/xdg_desktop_portal_utils.h" - #include "modules/video_capture/device_info_impl.h" -+#include "rtc_base/logging.h" - #include "rtc_base/string_encode.h" - #include "rtc_base/string_to_number.h" - - namespace webrtc { - namespace videocapturemodule { - --using xdg_portal::RequestSessionProxy; -- --constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -- - VideoType PipeWireRawFormatToVideoType(uint32_t id) { - switch (id) { - case SPA_VIDEO_FORMAT_I420: -@@ -215,181 +210,45 @@ bool PipeWireNode::ParseFormat(const spa_pod* param, - return cap->videoType != VideoType::kUnknown; - } - --PipeWireSession::PipeWireSession() -- : status_(VideoCaptureOptions::Status::UNINITIALIZED) {} -- --PipeWireSession::~PipeWireSession() { -- Cleanup(); --} -+CameraPortalNotifier::CameraPortalNotifier(PipeWireSession* session) -+ : session_(session) {} - --void PipeWireSession::Init(VideoCaptureOptions::Callback* callback) { -- callback_ = callback; -- cancellable_ = g_cancellable_new(); -- Scoped error; -- RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -- this); --} -- --// static --void PipeWireSession::OnProxyRequested(GObject* gobject, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- Scoped error; -- GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -- if (!proxy) { -- // Ignore the error caused by user cancelling the request via `cancellable_` -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -- << error->message; -- that->Finish(VideoCaptureOptions::Status::DENIED); -- return; -+void CameraPortalNotifier::OnCameraRequestResult( -+ xdg_portal::RequestResponse result, -+ int fd) { -+ if (result == xdg_portal::RequestResponse::kSuccess) { -+ session_->InitPipeWire(fd); -+ } else if (result == xdg_portal::RequestResponse::kUserCancelled) { -+ session_->Finish(VideoCaptureOptions::Status::DENIED); -+ } else { -+ session_->Finish(VideoCaptureOptions::Status::ERROR); - } -- -- RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -- that->ProxyRequested(proxy); - } - --void PipeWireSession::ProxyRequested(GDBusProxy* proxy) { -- GVariantBuilder builder; -- Scoped variant_string; -- std::string access_handle; -- -- proxy_ = proxy; -- connection_ = g_dbus_proxy_get_connection(proxy); -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- variant_string = -- g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string.get())); -- -- access_handle = -- xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -- access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -- access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -- -- RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -- g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -- reinterpret_cast(OnAccessResponse), -- this); --} -+PipeWireSession::PipeWireSession() {} - --// static --void PipeWireSession::OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped variant( -- g_dbus_proxy_call_finish(proxy, result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->Finish(VideoCaptureOptions::Status::ERROR); -- } --} -- --// static --void PipeWireSession::OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- uint32_t portal_response; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -- if (portal_response) { -- RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -- that->Finish(VideoCaptureOptions::Status::DENIED); -- return; -- } -- -- RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -- -- GVariantBuilder builder; -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- -- g_dbus_proxy_call( -- that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -- reinterpret_cast(OnOpenResponse), that); -+PipeWireSession::~PipeWireSession() { -+ Cleanup(); - } - --void PipeWireSession::OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped outlist; -- Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -- proxy, outlist.receive(), result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->Finish(VideoCaptureOptions::Status::ERROR); -- return; -- } -- -- int32_t index; -- g_variant_get(variant.get(), "(h)", &index); -- -- int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -- -- if (fd == -1) { -- RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -- << error->message; -- that->Finish(VideoCaptureOptions::Status::ERROR); -- return; -- } -+void PipeWireSession::Init(VideoCaptureOptions::Callback* callback, int fd) { -+ callback_ = callback; - -- if (!InitializePipeWire()) { -- that->Finish(VideoCaptureOptions::Status::UNAVAILABLE); -- return; -+ if (fd != -1) { -+ InitPipeWire(fd); -+ } else { -+ portal_notifier_ = std::make_unique(this); -+ portal_ = std::make_unique(portal_notifier_.get()); -+ portal_->Start(); - } -- -- if (!that->StartPipeWire(fd)) -- that->Finish(VideoCaptureOptions::Status::ERROR); - } - --void PipeWireSession::StopDBus() { -- if (access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, -- access_request_signal_id_); -- access_request_signal_id_ = 0; -- } -- if (cancellable_) { -- g_cancellable_cancel(cancellable_); -- g_object_unref(cancellable_); -- cancellable_ = nullptr; -- } -- if (proxy_) { -- g_object_unref(proxy_); -- proxy_ = nullptr; -- connection_ = nullptr; -- } -+void PipeWireSession::InitPipeWire(int fd) { -+ if (!InitializePipeWire()) -+ Finish(VideoCaptureOptions::Status::UNAVAILABLE); -+ -+ if (!StartPipeWire(fd)) -+ Finish(VideoCaptureOptions::Status::ERROR); - } - - bool PipeWireSession::StartPipeWire(int fd) { -@@ -523,7 +382,6 @@ void PipeWireSession::Finish(VideoCaptureOptions::Status status) { - - void PipeWireSession::Cleanup() { - StopPipeWire(); -- StopDBus(); - } - - } // namespace videocapturemodule -diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h -index 71cd1fed8b..7055e50fae 100644 ---- a/modules/video_capture/linux/pipewire_session.h -+++ b/modules/video_capture/linux/pipewire_session.h -@@ -11,7 +11,6 @@ - #ifndef MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - --#include - #include - #include - -@@ -21,6 +20,7 @@ - - #include "api/ref_counted_base.h" - #include "api/scoped_refptr.h" -+#include "modules/video_capture/linux/camera_portal.h" - #include "modules/video_capture/video_capture.h" - #include "modules/video_capture/video_capture_options.h" - -@@ -66,40 +66,33 @@ class PipeWireNode { - std::vector capabilities_; - }; - -+class CameraPortalNotifier : public CameraPortal::PortalNotifier { -+ public: -+ CameraPortalNotifier(PipeWireSession* session); -+ ~CameraPortalNotifier() = default; -+ -+ void OnCameraRequestResult(xdg_portal::RequestResponse result, -+ int fd) override; -+ -+ private: -+ PipeWireSession* session_; -+}; -+ - class PipeWireSession : public rtc::RefCountedNonVirtual { - public: - PipeWireSession(); - ~PipeWireSession(); - -- void Init(VideoCaptureOptions::Callback* callback); -- void CancelInit(); -+ void Init(VideoCaptureOptions::Callback* callback, int fd = -1); - - const std::deque& nodes() const { return nodes_; } - -+ friend class CameraPortalNotifier; - friend class PipeWireNode; - friend class VideoCaptureModulePipeWire; - - private: -- static void OnProxyRequested(GObject* object, -- GAsyncResult* result, -- gpointer user_data); -- void ProxyRequested(GDBusProxy* proxy); -- -- static void OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data); -- static void OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- void StopDBus(); -- -+ void InitPipeWire(int fd); - bool StartPipeWire(int fd); - void StopPipeWire(); - void PipeWireSync(); -@@ -124,13 +117,6 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - - VideoCaptureOptions::Callback* callback_ = nullptr; - -- GDBusConnection* connection_ = nullptr; -- GDBusProxy* proxy_ = nullptr; -- GCancellable* cancellable_ = nullptr; -- guint access_request_signal_id_ = 0; -- -- VideoCaptureOptions::Status status_; -- - struct pw_thread_loop* pw_main_loop_ = nullptr; - struct pw_context* pw_context_ = nullptr; - struct pw_core* pw_core_ = nullptr; -@@ -142,6 +128,8 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - int sync_seq_ = 0; - - std::deque nodes_; -+ std::unique_ptr portal_; -+ std::unique_ptr portal_notifier_; - }; - - } // namespace videocapturemodule -diff --git a/modules/video_capture/video_capture_options.cc b/modules/video_capture/video_capture_options.cc -index 444c23fcbc..203d0a604b 100644 ---- a/modules/video_capture/video_capture_options.cc -+++ b/modules/video_capture/video_capture_options.cc -@@ -33,7 +33,7 @@ void VideoCaptureOptions::Init(Callback* callback) { - if (allow_pipewire_) { - pipewire_session_ = - rtc::make_ref_counted(); -- pipewire_session_->Init(callback); -+ pipewire_session_->Init(callback, pipewire_fd_); - return; - } - #endif diff --git a/modules/video_capture/video_capture_options.h b/modules/video_capture/video_capture_options.h -index f35c6142b6..c90e035f37 100644 +index c90e035f37..18ec208ec5 100644 --- a/modules/video_capture/video_capture_options.h +++ b/modules/video_capture/video_capture_options.h -@@ -21,8 +21,7 @@ class PipeWireSession; - } - #endif +@@ -51,7 +51,7 @@ class RTC_EXPORT VideoCaptureOptions { --// An object that stores initialization parameters for screen and window --// capturers. -+// An object that stores initialization parameters for video capturers - class RTC_EXPORT VideoCaptureOptions { - public: - VideoCaptureOptions(); -@@ -60,6 +59,7 @@ class RTC_EXPORT VideoCaptureOptions { - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire() const { return allow_pipewire_; } - void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } -+ void set_pipewire_fd(int fd) { pipewire_fd_ = fd; } - rtc::scoped_refptr pipewire_session(); + void Init(Callback* callback); + +-#if defined(WEBRTC_LINUX) ++#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) + bool allow_v4l2() const { return allow_v4l2_; } + void set_allow_v4l2(bool allow) { allow_v4l2_ = allow; } + #endif +@@ -64,7 +64,7 @@ class RTC_EXPORT VideoCaptureOptions { #endif -@@ -69,6 +69,7 @@ class RTC_EXPORT VideoCaptureOptions { + private: +-#if defined(WEBRTC_LINUX) ++#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD) + bool allow_v4l2_ = false; #endif #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire_ = false; -+ int pipewire_fd_ = -1; - rtc::scoped_refptr pipewire_session_; - #endif - }; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0109.patch b/third_party/libwebrtc/moz-patch-stack/0109.patch index 3657231bd2ce3..ff1697109a8d2 100644 --- a/third_party/libwebrtc/moz-patch-stack/0109.patch +++ b/third_party/libwebrtc/moz-patch-stack/0109.patch @@ -1,33 +1,27 @@ -From: Jan Grulich -Date: Thu, 15 Jun 2023 09:13:00 +0000 -Subject: Bug 1724900: WebRTC backport: PipeWire video capture - set device - unique ID during initialization r=pehrsons,webrtc-reviewers +From: Michael Froman +Date: Wed, 5 Jul 2023 19:15:00 +0000 +Subject: Bug 1841864 - upstream commit 4baea5b07f should properly check size + of encoder_config_.simulcast_layers. r=jib -This is a simple backport of an WebRTC upstream change. - -Upstream commit: 4beafa38d546ab6c0bb423c12762f0c4568aa5ce - -Differential Revision: https://phabricator.services.mozilla.com/D176626 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b94558d76bd2943ba1063d7fade51c4d54d0db35 +Differential Revision: https://phabricator.services.mozilla.com/D182813 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/a7179d8d75313b6c9c76a496e10d102da019ff4f --- - modules/video_capture/linux/video_capture_pipewire.cc | 4 ++++ - 1 file changed, 4 insertions(+) + video/video_stream_encoder.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc -index c1e6aae5ea..99109e00e6 100644 ---- a/modules/video_capture/linux/video_capture_pipewire.cc -+++ b/modules/video_capture/linux/video_capture_pipewire.cc -@@ -62,6 +62,10 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) { - - node_id_ = id.value(); - -+ const int len = strlen(deviceUniqueId); -+ _deviceUniqueId = new (std::nothrow) char[len + 1]; -+ memcpy(_deviceUniqueId, deviceUniqueId, len + 1); -+ - return 0; - } +diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc +index e556ff9b8c..77af600ed6 100644 +--- a/video/video_stream_encoder.cc ++++ b/video/video_stream_encoder.cc +@@ -1396,7 +1396,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { + bool is_svc = false; + bool single_stream_or_non_first_inactive = true; +- for (size_t i = 1; i < encoder_config_.number_of_streams; ++i) { ++ for (size_t i = 1; i < encoder_config_.simulcast_layers.size(); ++i) { + if (encoder_config_.simulcast_layers[i].active) { + single_stream_or_non_first_inactive = false; + break; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0110.patch b/third_party/libwebrtc/moz-patch-stack/0110.patch index fa2c7e45b7d05..c7f2a2f0a5f9f 100644 --- a/third_party/libwebrtc/moz-patch-stack/0110.patch +++ b/third_party/libwebrtc/moz-patch-stack/0110.patch @@ -1,747 +1,27 @@ -From: Natalia Csoregi -Date: Thu, 15 Jun 2023 13:19:00 +0300 -Subject: Backed out 4 changesets (bug 1724900) for causing crashes on - getUserMedia-audio. CLOSED TREE +From: Mike Hommey +Date: Fri, 7 Jul 2023 00:58:00 +0000 +Subject: Bug 1841577 - Don't set WEBRTC_ENABLE_AVX2 on platforms that don't + have AVX2. r=mjf,webrtc-reviewers -Backed out changeset b94558d76bd2 (bug 1724900) -Backed out changeset 8ac9e05de573 (bug 1724900) -Backed out changeset 8ebb0f9ec0ae (bug 1724900) -Backed out changeset 241d7632685a (bug 1724900) -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/08cb4ca984b3aabd7881a042a28bdae29c0a5095 +Differential Revision: https://phabricator.services.mozilla.com/D182695 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/46fb51c90709be64c35946a8cf69195121441024 --- - modules/video_capture/BUILD.gn | 2 - - modules/video_capture/linux/camera_portal.cc | 242 ------------------ - modules/video_capture/linux/camera_portal.h | 47 ---- - .../video_capture/linux/pipewire_session.cc | 200 ++++++++++++--- - .../video_capture/linux/pipewire_session.h | 48 ++-- - .../linux/video_capture_pipewire.cc | 4 - - .../video_capture/video_capture_options.cc | 2 +- - modules/video_capture/video_capture_options.h | 5 +- - 8 files changed, 204 insertions(+), 346 deletions(-) - delete mode 100644 modules/video_capture/linux/camera_portal.cc - delete mode 100644 modules/video_capture/linux/camera_portal.h + webrtc.gni | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn -index 1e32e87fa8..65468cecd7 100644 ---- a/modules/video_capture/BUILD.gn -+++ b/modules/video_capture/BUILD.gn -@@ -82,8 +82,6 @@ if (!build_with_chromium || is_linux || is_chromeos) { - - if (rtc_use_pipewire) { - sources += [ -- "linux/camera_portal.cc", -- "linux/camera_portal.h", - "linux/device_info_pipewire.cc", - "linux/device_info_pipewire.h", - "linux/pipewire_session.cc", -diff --git a/modules/video_capture/linux/camera_portal.cc b/modules/video_capture/linux/camera_portal.cc -deleted file mode 100644 -index d217dc7251..0000000000 ---- a/modules/video_capture/linux/camera_portal.cc -+++ /dev/null -@@ -1,242 +0,0 @@ --/* -- * Copyright (c) 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 "modules/video_capture/linux/camera_portal.h" -- --#include --#include -- --#include "modules/portal/xdg_desktop_portal_utils.h" -- --namespace webrtc { -- --using xdg_portal::RequestResponse; --using xdg_portal::RequestResponseFromPortalResponse; --using xdg_portal::RequestSessionProxy; -- --constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -- --class CameraPortalPrivate { -- public: -- explicit CameraPortalPrivate(CameraPortal::PortalNotifier* notifier); -- ~CameraPortalPrivate(); -- -- void Start(); -- -- private: -- void OnPortalDone(xdg_portal::RequestResponse result, int fd = -1); -- -- static void OnProxyRequested(GObject* object, -- GAsyncResult* result, -- gpointer user_data); -- void ProxyRequested(GDBusProxy* proxy); -- -- static void OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data); -- static void OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- -- CameraPortal::PortalNotifier* notifier_ = nullptr; -- -- GDBusConnection* connection_ = nullptr; -- GDBusProxy* proxy_ = nullptr; -- GCancellable* cancellable_ = nullptr; -- guint access_request_signal_id_ = 0; --}; -- --CameraPortalPrivate::CameraPortalPrivate(CameraPortal::PortalNotifier* notifier) -- : notifier_(notifier) {} -- --CameraPortalPrivate::~CameraPortalPrivate() { -- if (access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, -- access_request_signal_id_); -- access_request_signal_id_ = 0; -- } -- if (cancellable_) { -- g_cancellable_cancel(cancellable_); -- g_object_unref(cancellable_); -- cancellable_ = nullptr; -- } -- if (proxy_) { -- g_object_unref(proxy_); -- proxy_ = nullptr; -- connection_ = nullptr; -- } --} -- --void CameraPortalPrivate::Start() { -- cancellable_ = g_cancellable_new(); -- Scoped error; -- RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -- this); --} -- --// static --void CameraPortalPrivate::OnProxyRequested(GObject* gobject, -- GAsyncResult* result, -- gpointer user_data) { -- CameraPortalPrivate* that = static_cast(user_data); -- Scoped error; -- GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -- if (!proxy) { -- // Ignore the error caused by user cancelling the request via `cancellable_` -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -- << error->message; -- that->OnPortalDone(RequestResponse::kError); -- return; -- } -- -- RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -- that->ProxyRequested(proxy); --} -- --void CameraPortalPrivate::ProxyRequested(GDBusProxy* proxy) { -- GVariantBuilder builder; -- Scoped variant_string; -- std::string access_handle; -- -- proxy_ = proxy; -- connection_ = g_dbus_proxy_get_connection(proxy); -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- variant_string = -- g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string.get())); -- -- access_handle = -- xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -- access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -- access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -- -- RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -- g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -- reinterpret_cast(OnAccessResponse), -- this); --} -- --// static --void CameraPortalPrivate::OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- CameraPortalPrivate* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped variant( -- g_dbus_proxy_call_finish(proxy, result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->OnPortalDone(RequestResponse::kError); -- } --} -- --// static --void CameraPortalPrivate::OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- CameraPortalPrivate* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- uint32_t portal_response; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -- if (portal_response) { -- RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -- that->OnPortalDone(RequestResponseFromPortalResponse(portal_response)); -- return; -- } -- -- RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -- -- GVariantBuilder builder; -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- -- g_dbus_proxy_call( -- that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -- reinterpret_cast(OnOpenResponse), that); --} -- --void CameraPortalPrivate::OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- CameraPortalPrivate* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped outlist; -- Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -- proxy, outlist.receive(), result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->OnPortalDone(RequestResponse::kError); -- return; -- } -- -- int32_t index; -- g_variant_get(variant.get(), "(h)", &index); -- -- int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -- -- if (fd == -1) { -- RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -- << error->message; -- that->OnPortalDone(RequestResponse::kError); -- return; -- } -- -- that->OnPortalDone(RequestResponse::kSuccess, fd); --} -- --void CameraPortalPrivate::OnPortalDone(RequestResponse result, int fd) { -- notifier_->OnCameraRequestResult(result, fd); --} -- --CameraPortal::CameraPortal(PortalNotifier* notifier) -- : private_(std::make_unique(notifier)) {} -- --CameraPortal::~CameraPortal() {} -- --void CameraPortal::Start() { -- private_->Start(); --} -- --} // namespace webrtc -diff --git a/modules/video_capture/linux/camera_portal.h b/modules/video_capture/linux/camera_portal.h -deleted file mode 100644 -index 36f2ec8b8a..0000000000 ---- a/modules/video_capture/linux/camera_portal.h -+++ /dev/null -@@ -1,47 +0,0 @@ --/* -- * Copyright (c) 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 MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ --#define MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -- --#include --#include -- --#include "modules/portal/portal_request_response.h" --#include "rtc_base/system/rtc_export.h" -- --namespace webrtc { -- --class CameraPortalPrivate; -- --class RTC_EXPORT CameraPortal { -- public: -- class PortalNotifier { -- public: -- virtual void OnCameraRequestResult(xdg_portal::RequestResponse result, -- int fd) = 0; -- -- protected: -- PortalNotifier() = default; -- virtual ~PortalNotifier() = default; -- }; -- -- explicit CameraPortal(PortalNotifier* notifier); -- ~CameraPortal(); -- -- void Start(); -- -- private: -- std::unique_ptr private_; --}; -- --} // namespace webrtc -- --#endif // MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc -index f2680b2816..14d557d6c1 100644 ---- a/modules/video_capture/linux/pipewire_session.cc -+++ b/modules/video_capture/linux/pipewire_session.cc -@@ -10,6 +10,7 @@ - - #include "modules/video_capture/linux/pipewire_session.h" - -+#include - #include - #include - #include -@@ -18,14 +19,18 @@ - - #include "common_video/libyuv/include/webrtc_libyuv.h" - #include "modules/portal/pipewire_utils.h" -+#include "modules/portal/xdg_desktop_portal_utils.h" - #include "modules/video_capture/device_info_impl.h" --#include "rtc_base/logging.h" - #include "rtc_base/string_encode.h" - #include "rtc_base/string_to_number.h" - - namespace webrtc { - namespace videocapturemodule { - -+using xdg_portal::RequestSessionProxy; -+ -+constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -+ - VideoType PipeWireRawFormatToVideoType(uint32_t id) { - switch (id) { - case SPA_VIDEO_FORMAT_I420: -@@ -210,45 +215,181 @@ bool PipeWireNode::ParseFormat(const spa_pod* param, - return cap->videoType != VideoType::kUnknown; - } - --CameraPortalNotifier::CameraPortalNotifier(PipeWireSession* session) -- : session_(session) {} -- --void CameraPortalNotifier::OnCameraRequestResult( -- xdg_portal::RequestResponse result, -- int fd) { -- if (result == xdg_portal::RequestResponse::kSuccess) { -- session_->InitPipeWire(fd); -- } else if (result == xdg_portal::RequestResponse::kUserCancelled) { -- session_->Finish(VideoCaptureOptions::Status::DENIED); -- } else { -- session_->Finish(VideoCaptureOptions::Status::ERROR); -- } --} -- --PipeWireSession::PipeWireSession() {} -+PipeWireSession::PipeWireSession() -+ : status_(VideoCaptureOptions::Status::UNINITIALIZED) {} - - PipeWireSession::~PipeWireSession() { - Cleanup(); - } - --void PipeWireSession::Init(VideoCaptureOptions::Callback* callback, int fd) { -+void PipeWireSession::Init(VideoCaptureOptions::Callback* callback) { - callback_ = callback; -+ cancellable_ = g_cancellable_new(); -+ Scoped error; -+ RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -+ this); -+} - -- if (fd != -1) { -- InitPipeWire(fd); -- } else { -- portal_notifier_ = std::make_unique(this); -- portal_ = std::make_unique(portal_notifier_.get()); -- portal_->Start(); -+// static -+void PipeWireSession::OnProxyRequested(GObject* gobject, -+ GAsyncResult* result, -+ gpointer user_data) { -+ PipeWireSession* that = static_cast(user_data); -+ Scoped error; -+ GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -+ if (!proxy) { -+ // Ignore the error caused by user cancelling the request via `cancellable_` -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -+ << error->message; -+ that->Finish(VideoCaptureOptions::Status::DENIED); -+ return; - } -+ -+ RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -+ that->ProxyRequested(proxy); -+} -+ -+void PipeWireSession::ProxyRequested(GDBusProxy* proxy) { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ std::string access_handle; -+ -+ proxy_ = proxy; -+ connection_ = g_dbus_proxy_get_connection(proxy); -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ variant_string = -+ g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ access_handle = -+ xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -+ access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -+ access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -+ -+ RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -+ g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -+ reinterpret_cast(OnAccessResponse), -+ this); - } - --void PipeWireSession::InitPipeWire(int fd) { -- if (!InitializePipeWire()) -- Finish(VideoCaptureOptions::Status::UNAVAILABLE); -+// static -+void PipeWireSession::OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ PipeWireSession* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->Finish(VideoCaptureOptions::Status::ERROR); -+ } -+} -+ -+// static -+void PipeWireSession::OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ PipeWireSession* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ uint32_t portal_response; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -+ if (portal_response) { -+ RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -+ that->Finish(VideoCaptureOptions::Status::DENIED); -+ return; -+ } - -- if (!StartPipeWire(fd)) -- Finish(VideoCaptureOptions::Status::ERROR); -+ RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -+ -+ GVariantBuilder builder; -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ -+ g_dbus_proxy_call( -+ that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -+ reinterpret_cast(OnOpenResponse), that); -+} -+ -+void PipeWireSession::OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ PipeWireSession* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped outlist; -+ Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -+ proxy, outlist.receive(), result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->Finish(VideoCaptureOptions::Status::ERROR); -+ return; -+ } -+ -+ int32_t index; -+ g_variant_get(variant.get(), "(h)", &index); -+ -+ int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -+ -+ if (fd == -1) { -+ RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -+ << error->message; -+ that->Finish(VideoCaptureOptions::Status::ERROR); -+ return; -+ } -+ -+ if (!InitializePipeWire()) { -+ that->Finish(VideoCaptureOptions::Status::UNAVAILABLE); -+ return; -+ } -+ -+ if (!that->StartPipeWire(fd)) -+ that->Finish(VideoCaptureOptions::Status::ERROR); -+} -+ -+void PipeWireSession::StopDBus() { -+ if (access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, -+ access_request_signal_id_); -+ access_request_signal_id_ = 0; -+ } -+ if (cancellable_) { -+ g_cancellable_cancel(cancellable_); -+ g_object_unref(cancellable_); -+ cancellable_ = nullptr; -+ } -+ if (proxy_) { -+ g_object_unref(proxy_); -+ proxy_ = nullptr; -+ connection_ = nullptr; -+ } - } - - bool PipeWireSession::StartPipeWire(int fd) { -@@ -382,6 +523,7 @@ void PipeWireSession::Finish(VideoCaptureOptions::Status status) { - - void PipeWireSession::Cleanup() { - StopPipeWire(); -+ StopDBus(); - } - - } // namespace videocapturemodule -diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h -index 7055e50fae..71cd1fed8b 100644 ---- a/modules/video_capture/linux/pipewire_session.h -+++ b/modules/video_capture/linux/pipewire_session.h -@@ -11,6 +11,7 @@ - #ifndef MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - -+#include - #include - #include - -@@ -20,7 +21,6 @@ - - #include "api/ref_counted_base.h" - #include "api/scoped_refptr.h" --#include "modules/video_capture/linux/camera_portal.h" - #include "modules/video_capture/video_capture.h" - #include "modules/video_capture/video_capture_options.h" - -@@ -66,33 +66,40 @@ class PipeWireNode { - std::vector capabilities_; - }; - --class CameraPortalNotifier : public CameraPortal::PortalNotifier { -- public: -- CameraPortalNotifier(PipeWireSession* session); -- ~CameraPortalNotifier() = default; -- -- void OnCameraRequestResult(xdg_portal::RequestResponse result, -- int fd) override; -- -- private: -- PipeWireSession* session_; --}; -- - class PipeWireSession : public rtc::RefCountedNonVirtual { - public: - PipeWireSession(); - ~PipeWireSession(); - -- void Init(VideoCaptureOptions::Callback* callback, int fd = -1); -+ void Init(VideoCaptureOptions::Callback* callback); -+ void CancelInit(); - - const std::deque& nodes() const { return nodes_; } - -- friend class CameraPortalNotifier; - friend class PipeWireNode; - friend class VideoCaptureModulePipeWire; - - private: -- void InitPipeWire(int fd); -+ static void OnProxyRequested(GObject* object, -+ GAsyncResult* result, -+ gpointer user_data); -+ void ProxyRequested(GDBusProxy* proxy); -+ -+ static void OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ static void OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ void StopDBus(); -+ - bool StartPipeWire(int fd); - void StopPipeWire(); - void PipeWireSync(); -@@ -117,6 +124,13 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - - VideoCaptureOptions::Callback* callback_ = nullptr; - -+ GDBusConnection* connection_ = nullptr; -+ GDBusProxy* proxy_ = nullptr; -+ GCancellable* cancellable_ = nullptr; -+ guint access_request_signal_id_ = 0; -+ -+ VideoCaptureOptions::Status status_; -+ - struct pw_thread_loop* pw_main_loop_ = nullptr; - struct pw_context* pw_context_ = nullptr; - struct pw_core* pw_core_ = nullptr; -@@ -128,8 +142,6 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - int sync_seq_ = 0; - - std::deque nodes_; -- std::unique_ptr portal_; -- std::unique_ptr portal_notifier_; - }; - - } // namespace videocapturemodule -diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc -index 99109e00e6..c1e6aae5ea 100644 ---- a/modules/video_capture/linux/video_capture_pipewire.cc -+++ b/modules/video_capture/linux/video_capture_pipewire.cc -@@ -62,10 +62,6 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) { - - node_id_ = id.value(); - -- const int len = strlen(deviceUniqueId); -- _deviceUniqueId = new (std::nothrow) char[len + 1]; -- memcpy(_deviceUniqueId, deviceUniqueId, len + 1); -- - return 0; - } - -diff --git a/modules/video_capture/video_capture_options.cc b/modules/video_capture/video_capture_options.cc -index 203d0a604b..444c23fcbc 100644 ---- a/modules/video_capture/video_capture_options.cc -+++ b/modules/video_capture/video_capture_options.cc -@@ -33,7 +33,7 @@ void VideoCaptureOptions::Init(Callback* callback) { - if (allow_pipewire_) { - pipewire_session_ = - rtc::make_ref_counted(); -- pipewire_session_->Init(callback, pipewire_fd_); -+ pipewire_session_->Init(callback); - return; - } - #endif -diff --git a/modules/video_capture/video_capture_options.h b/modules/video_capture/video_capture_options.h -index c90e035f37..f35c6142b6 100644 ---- a/modules/video_capture/video_capture_options.h -+++ b/modules/video_capture/video_capture_options.h -@@ -21,7 +21,8 @@ class PipeWireSession; - } - #endif - --// An object that stores initialization parameters for video capturers -+// An object that stores initialization parameters for screen and window -+// capturers. - class RTC_EXPORT VideoCaptureOptions { - public: - VideoCaptureOptions(); -@@ -59,7 +60,6 @@ class RTC_EXPORT VideoCaptureOptions { - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire() const { return allow_pipewire_; } - void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } -- void set_pipewire_fd(int fd) { pipewire_fd_ = fd; } - rtc::scoped_refptr pipewire_session(); - #endif - -@@ -69,7 +69,6 @@ class RTC_EXPORT VideoCaptureOptions { - #endif - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire_ = false; -- int pipewire_fd_ = -1; - rtc::scoped_refptr pipewire_session_; - #endif - }; +diff --git a/webrtc.gni b/webrtc.gni +index e4ed834aec..15cde6ca33 100644 +--- a/webrtc.gni ++++ b/webrtc.gni +@@ -290,7 +290,7 @@ declare_args() { + + # Set this to true to enable the avx2 support in webrtc. + # TODO: Make sure that AVX2 works also for non-clang compilers. +- if (is_clang == true) { ++ if (is_clang == true && (target_cpu == "x86" || target_cpu == "x64")) { + rtc_enable_avx2 = true + } else { + rtc_enable_avx2 = false -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0111.patch b/third_party/libwebrtc/moz-patch-stack/0111.patch index d41d3d87d16cf..9ccc782a4863f 100644 --- a/third_party/libwebrtc/moz-patch-stack/0111.patch +++ b/third_party/libwebrtc/moz-patch-stack/0111.patch @@ -1,732 +1,29 @@ -From: Jan Grulich -Date: Thu, 15 Jun 2023 12:41:00 +0000 -Subject: Bug 1724900: WebRTC backport: PipeWire video capture: split portal - and PipeWire implementations r=pehrsons,webrtc-reviewers +From: Byron Campen +Date: Thu, 20 Jul 2023 14:24:00 +0000 +Subject: Bug 1838080: Remove this duplicate init (that's also on the wrong + thread). r=pehrsons,webrtc-reviewers -This is a simple backport of an WebRTC upstream change. +This was causing assertions. -Upstream commit: 56d126074e5fb62a65e4e14cce44466ce7297770 - -Differential Revision: https://phabricator.services.mozilla.com/D178937 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/0472c2c907759c916999889e8d7ce3f3ad3e7e42 +Differential Revision: https://phabricator.services.mozilla.com/D179731 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/6ac6592a04a839a6152d5ad5f0778f63dbbd6b1b --- - modules/video_capture/BUILD.gn | 2 + - modules/video_capture/linux/camera_portal.cc | 242 ++++++++++++++++++ - modules/video_capture/linux/camera_portal.h | 47 ++++ - .../video_capture/linux/pipewire_session.cc | 200 +++------------ - .../video_capture/linux/pipewire_session.h | 48 ++-- - .../video_capture/video_capture_options.cc | 2 +- - modules/video_capture/video_capture_options.h | 5 +- - 7 files changed, 342 insertions(+), 204 deletions(-) - create mode 100644 modules/video_capture/linux/camera_portal.cc - create mode 100644 modules/video_capture/linux/camera_portal.h + audio/channel_send.cc | 2 -- + 1 file changed, 2 deletions(-) -diff --git a/modules/video_capture/BUILD.gn b/modules/video_capture/BUILD.gn -index 65468cecd7..1e32e87fa8 100644 ---- a/modules/video_capture/BUILD.gn -+++ b/modules/video_capture/BUILD.gn -@@ -82,6 +82,8 @@ if (!build_with_chromium || is_linux || is_chromeos) { - - if (rtc_use_pipewire) { - sources += [ -+ "linux/camera_portal.cc", -+ "linux/camera_portal.h", - "linux/device_info_pipewire.cc", - "linux/device_info_pipewire.h", - "linux/pipewire_session.cc", -diff --git a/modules/video_capture/linux/camera_portal.cc b/modules/video_capture/linux/camera_portal.cc -new file mode 100644 -index 0000000000..d217dc7251 ---- /dev/null -+++ b/modules/video_capture/linux/camera_portal.cc -@@ -0,0 +1,242 @@ -+/* -+ * Copyright (c) 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 "modules/video_capture/linux/camera_portal.h" -+ -+#include -+#include -+ -+#include "modules/portal/xdg_desktop_portal_utils.h" -+ -+namespace webrtc { -+ -+using xdg_portal::RequestResponse; -+using xdg_portal::RequestResponseFromPortalResponse; -+using xdg_portal::RequestSessionProxy; -+ -+constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -+ -+class CameraPortalPrivate { -+ public: -+ explicit CameraPortalPrivate(CameraPortal::PortalNotifier* notifier); -+ ~CameraPortalPrivate(); -+ -+ void Start(); -+ -+ private: -+ void OnPortalDone(xdg_portal::RequestResponse result, int fd = -1); -+ -+ static void OnProxyRequested(GObject* object, -+ GAsyncResult* result, -+ gpointer user_data); -+ void ProxyRequested(GDBusProxy* proxy); -+ -+ static void OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ static void OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ -+ CameraPortal::PortalNotifier* notifier_ = nullptr; -+ -+ GDBusConnection* connection_ = nullptr; -+ GDBusProxy* proxy_ = nullptr; -+ GCancellable* cancellable_ = nullptr; -+ guint access_request_signal_id_ = 0; -+}; -+ -+CameraPortalPrivate::CameraPortalPrivate(CameraPortal::PortalNotifier* notifier) -+ : notifier_(notifier) {} -+ -+CameraPortalPrivate::~CameraPortalPrivate() { -+ if (access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, -+ access_request_signal_id_); -+ access_request_signal_id_ = 0; -+ } -+ if (cancellable_) { -+ g_cancellable_cancel(cancellable_); -+ g_object_unref(cancellable_); -+ cancellable_ = nullptr; -+ } -+ if (proxy_) { -+ g_object_unref(proxy_); -+ proxy_ = nullptr; -+ connection_ = nullptr; -+ } -+} -+ -+void CameraPortalPrivate::Start() { -+ cancellable_ = g_cancellable_new(); -+ Scoped error; -+ RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -+ this); -+} -+ -+// static -+void CameraPortalPrivate::OnProxyRequested(GObject* gobject, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ Scoped error; -+ GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -+ if (!proxy) { -+ // Ignore the error caused by user cancelling the request via `cancellable_` -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -+ << error->message; -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -+ that->ProxyRequested(proxy); -+} -+ -+void CameraPortalPrivate::ProxyRequested(GDBusProxy* proxy) { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ std::string access_handle; -+ -+ proxy_ = proxy; -+ connection_ = g_dbus_proxy_get_connection(proxy); -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ variant_string = -+ g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ access_handle = -+ xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -+ access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -+ access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -+ -+ RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -+ g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -+ reinterpret_cast(OnAccessResponse), -+ this); -+} -+ -+// static -+void CameraPortalPrivate::OnAccessResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->OnPortalDone(RequestResponse::kError); -+ } -+} -+ -+// static -+void CameraPortalPrivate::OnResponseSignalEmitted(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ uint32_t portal_response; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -+ if (portal_response) { -+ RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -+ that->OnPortalDone(RequestResponseFromPortalResponse(portal_response)); -+ return; -+ } -+ -+ RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -+ -+ GVariantBuilder builder; -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ -+ g_dbus_proxy_call( -+ that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -+ reinterpret_cast(OnOpenResponse), that); -+} -+ -+void CameraPortalPrivate::OnOpenResponse(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ CameraPortalPrivate* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped outlist; -+ Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -+ proxy, outlist.receive(), result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -+ if (that->access_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->access_request_signal_id_); -+ that->access_request_signal_id_ = 0; -+ } -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ int32_t index; -+ g_variant_get(variant.get(), "(h)", &index); -+ -+ int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -+ -+ if (fd == -1) { -+ RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -+ << error->message; -+ that->OnPortalDone(RequestResponse::kError); -+ return; -+ } -+ -+ that->OnPortalDone(RequestResponse::kSuccess, fd); -+} -+ -+void CameraPortalPrivate::OnPortalDone(RequestResponse result, int fd) { -+ notifier_->OnCameraRequestResult(result, fd); -+} -+ -+CameraPortal::CameraPortal(PortalNotifier* notifier) -+ : private_(std::make_unique(notifier)) {} -+ -+CameraPortal::~CameraPortal() {} -+ -+void CameraPortal::Start() { -+ private_->Start(); -+} -+ -+} // namespace webrtc -diff --git a/modules/video_capture/linux/camera_portal.h b/modules/video_capture/linux/camera_portal.h -new file mode 100644 -index 0000000000..36f2ec8b8a ---- /dev/null -+++ b/modules/video_capture/linux/camera_portal.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (c) 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 MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -+#define MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -+ -+#include -+#include -+ -+#include "modules/portal/portal_request_response.h" -+#include "rtc_base/system/rtc_export.h" -+ -+namespace webrtc { -+ -+class CameraPortalPrivate; -+ -+class RTC_EXPORT CameraPortal { -+ public: -+ class PortalNotifier { -+ public: -+ virtual void OnCameraRequestResult(xdg_portal::RequestResponse result, -+ int fd) = 0; -+ -+ protected: -+ PortalNotifier() = default; -+ virtual ~PortalNotifier() = default; -+ }; -+ -+ explicit CameraPortal(PortalNotifier* notifier); -+ ~CameraPortal(); -+ -+ void Start(); -+ -+ private: -+ std::unique_ptr private_; -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_VIDEO_CAPTURE_LINUX_CAMERA_PORTAL_H_ -diff --git a/modules/video_capture/linux/pipewire_session.cc b/modules/video_capture/linux/pipewire_session.cc -index 14d557d6c1..f2680b2816 100644 ---- a/modules/video_capture/linux/pipewire_session.cc -+++ b/modules/video_capture/linux/pipewire_session.cc -@@ -10,7 +10,6 @@ - - #include "modules/video_capture/linux/pipewire_session.h" - --#include - #include - #include - #include -@@ -19,18 +18,14 @@ - - #include "common_video/libyuv/include/webrtc_libyuv.h" - #include "modules/portal/pipewire_utils.h" --#include "modules/portal/xdg_desktop_portal_utils.h" - #include "modules/video_capture/device_info_impl.h" -+#include "rtc_base/logging.h" - #include "rtc_base/string_encode.h" - #include "rtc_base/string_to_number.h" - - namespace webrtc { - namespace videocapturemodule { - --using xdg_portal::RequestSessionProxy; -- --constexpr char kCameraInterfaceName[] = "org.freedesktop.portal.Camera"; -- - VideoType PipeWireRawFormatToVideoType(uint32_t id) { - switch (id) { - case SPA_VIDEO_FORMAT_I420: -@@ -215,181 +210,45 @@ bool PipeWireNode::ParseFormat(const spa_pod* param, - return cap->videoType != VideoType::kUnknown; - } - --PipeWireSession::PipeWireSession() -- : status_(VideoCaptureOptions::Status::UNINITIALIZED) {} -- --PipeWireSession::~PipeWireSession() { -- Cleanup(); --} -+CameraPortalNotifier::CameraPortalNotifier(PipeWireSession* session) -+ : session_(session) {} - --void PipeWireSession::Init(VideoCaptureOptions::Callback* callback) { -- callback_ = callback; -- cancellable_ = g_cancellable_new(); -- Scoped error; -- RequestSessionProxy(kCameraInterfaceName, OnProxyRequested, cancellable_, -- this); --} -- --// static --void PipeWireSession::OnProxyRequested(GObject* gobject, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- Scoped error; -- GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -- if (!proxy) { -- // Ignore the error caused by user cancelling the request via `cancellable_` -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to get a proxy for the portal: " -- << error->message; -- that->Finish(VideoCaptureOptions::Status::DENIED); -- return; -+void CameraPortalNotifier::OnCameraRequestResult( -+ xdg_portal::RequestResponse result, -+ int fd) { -+ if (result == xdg_portal::RequestResponse::kSuccess) { -+ session_->InitPipeWire(fd); -+ } else if (result == xdg_portal::RequestResponse::kUserCancelled) { -+ session_->Finish(VideoCaptureOptions::Status::DENIED); -+ } else { -+ session_->Finish(VideoCaptureOptions::Status::ERROR); - } -- -- RTC_LOG(LS_VERBOSE) << "Successfully created proxy for the portal."; -- that->ProxyRequested(proxy); +diff --git a/audio/channel_send.cc b/audio/channel_send.cc +index f6b9767655..f9283c3a00 100644 +--- a/audio/channel_send.cc ++++ b/audio/channel_send.cc +@@ -534,8 +534,6 @@ ChannelSend::ChannelSend( + + int error = audio_coding_->RegisterTransportCallback(this); + RTC_DCHECK_EQ(0, error); +- if (frame_transformer) +- InitFrameTransformerDelegate(std::move(frame_transformer)); } --void PipeWireSession::ProxyRequested(GDBusProxy* proxy) { -- GVariantBuilder builder; -- Scoped variant_string; -- std::string access_handle; -- -- proxy_ = proxy; -- connection_ = g_dbus_proxy_get_connection(proxy); -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- variant_string = -- g_strdup_printf("capture%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string.get())); -- -- access_handle = -- xdg_portal::PrepareSignalHandle(variant_string.get(), connection_); -- access_request_signal_id_ = xdg_portal::SetupRequestResponseSignal( -- access_handle.c_str(), OnResponseSignalEmitted, this, connection_); -- -- RTC_LOG(LS_VERBOSE) << "Requesting camera access from the portal."; -- g_dbus_proxy_call(proxy_, "AccessCamera", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, cancellable_, -- reinterpret_cast(OnAccessResponse), -- this); --} -+PipeWireSession::PipeWireSession() {} - --// static --void PipeWireSession::OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped variant( -- g_dbus_proxy_call_finish(proxy, result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to access portal:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->Finish(VideoCaptureOptions::Status::ERROR); -- } --} -- --// static --void PipeWireSession::OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- uint32_t portal_response; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -- if (portal_response) { -- RTC_LOG(LS_INFO) << "Camera access denied by the XDG portal."; -- that->Finish(VideoCaptureOptions::Status::DENIED); -- return; -- } -- -- RTC_LOG(LS_VERBOSE) << "Camera access granted by the XDG portal."; -- -- GVariantBuilder builder; -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- -- g_dbus_proxy_call( -- that->proxy_, "OpenPipeWireRemote", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout_msec=*/-1, that->cancellable_, -- reinterpret_cast(OnOpenResponse), that); -+PipeWireSession::~PipeWireSession() { -+ Cleanup(); - } - --void PipeWireSession::OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data) { -- PipeWireSession* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- Scoped error; -- Scoped outlist; -- Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -- proxy, outlist.receive(), result, error.receive())); -- if (!variant) { -- if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to open PipeWire remote:" << error->message; -- if (that->access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->access_request_signal_id_); -- that->access_request_signal_id_ = 0; -- } -- that->Finish(VideoCaptureOptions::Status::ERROR); -- return; -- } -- -- int32_t index; -- g_variant_get(variant.get(), "(h)", &index); -- -- int fd = g_unix_fd_list_get(outlist.get(), index, error.receive()); -- -- if (fd == -1) { -- RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -- << error->message; -- that->Finish(VideoCaptureOptions::Status::ERROR); -- return; -- } -+void PipeWireSession::Init(VideoCaptureOptions::Callback* callback, int fd) { -+ callback_ = callback; - -- if (!InitializePipeWire()) { -- that->Finish(VideoCaptureOptions::Status::UNAVAILABLE); -- return; -+ if (fd != -1) { -+ InitPipeWire(fd); -+ } else { -+ portal_notifier_ = std::make_unique(this); -+ portal_ = std::make_unique(portal_notifier_.get()); -+ portal_->Start(); - } -- -- if (!that->StartPipeWire(fd)) -- that->Finish(VideoCaptureOptions::Status::ERROR); - } - --void PipeWireSession::StopDBus() { -- if (access_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, -- access_request_signal_id_); -- access_request_signal_id_ = 0; -- } -- if (cancellable_) { -- g_cancellable_cancel(cancellable_); -- g_object_unref(cancellable_); -- cancellable_ = nullptr; -- } -- if (proxy_) { -- g_object_unref(proxy_); -- proxy_ = nullptr; -- connection_ = nullptr; -- } -+void PipeWireSession::InitPipeWire(int fd) { -+ if (!InitializePipeWire()) -+ Finish(VideoCaptureOptions::Status::UNAVAILABLE); -+ -+ if (!StartPipeWire(fd)) -+ Finish(VideoCaptureOptions::Status::ERROR); - } - - bool PipeWireSession::StartPipeWire(int fd) { -@@ -523,7 +382,6 @@ void PipeWireSession::Finish(VideoCaptureOptions::Status status) { - - void PipeWireSession::Cleanup() { - StopPipeWire(); -- StopDBus(); - } - - } // namespace videocapturemodule -diff --git a/modules/video_capture/linux/pipewire_session.h b/modules/video_capture/linux/pipewire_session.h -index 71cd1fed8b..7055e50fae 100644 ---- a/modules/video_capture/linux/pipewire_session.h -+++ b/modules/video_capture/linux/pipewire_session.h -@@ -11,7 +11,6 @@ - #ifndef MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - #define MODULES_VIDEO_CAPTURE_LINUX_PIPEWIRE_SESSION_H_ - --#include - #include - #include - -@@ -21,6 +20,7 @@ - - #include "api/ref_counted_base.h" - #include "api/scoped_refptr.h" -+#include "modules/video_capture/linux/camera_portal.h" - #include "modules/video_capture/video_capture.h" - #include "modules/video_capture/video_capture_options.h" - -@@ -66,40 +66,33 @@ class PipeWireNode { - std::vector capabilities_; - }; - -+class CameraPortalNotifier : public CameraPortal::PortalNotifier { -+ public: -+ CameraPortalNotifier(PipeWireSession* session); -+ ~CameraPortalNotifier() = default; -+ -+ void OnCameraRequestResult(xdg_portal::RequestResponse result, -+ int fd) override; -+ -+ private: -+ PipeWireSession* session_; -+}; -+ - class PipeWireSession : public rtc::RefCountedNonVirtual { - public: - PipeWireSession(); - ~PipeWireSession(); - -- void Init(VideoCaptureOptions::Callback* callback); -- void CancelInit(); -+ void Init(VideoCaptureOptions::Callback* callback, int fd = -1); - - const std::deque& nodes() const { return nodes_; } - -+ friend class CameraPortalNotifier; - friend class PipeWireNode; - friend class VideoCaptureModulePipeWire; - - private: -- static void OnProxyRequested(GObject* object, -- GAsyncResult* result, -- gpointer user_data); -- void ProxyRequested(GDBusProxy* proxy); -- -- static void OnAccessResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnResponseSignalEmitted(GDBusConnection* connection, -- const char* sender_name, -- const char* object_path, -- const char* interface_name, -- const char* signal_name, -- GVariant* parameters, -- gpointer user_data); -- static void OnOpenResponse(GDBusProxy* proxy, -- GAsyncResult* result, -- gpointer user_data); -- void StopDBus(); -- -+ void InitPipeWire(int fd); - bool StartPipeWire(int fd); - void StopPipeWire(); - void PipeWireSync(); -@@ -124,13 +117,6 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - - VideoCaptureOptions::Callback* callback_ = nullptr; - -- GDBusConnection* connection_ = nullptr; -- GDBusProxy* proxy_ = nullptr; -- GCancellable* cancellable_ = nullptr; -- guint access_request_signal_id_ = 0; -- -- VideoCaptureOptions::Status status_; -- - struct pw_thread_loop* pw_main_loop_ = nullptr; - struct pw_context* pw_context_ = nullptr; - struct pw_core* pw_core_ = nullptr; -@@ -142,6 +128,8 @@ class PipeWireSession : public rtc::RefCountedNonVirtual { - int sync_seq_ = 0; - - std::deque nodes_; -+ std::unique_ptr portal_; -+ std::unique_ptr portal_notifier_; - }; - - } // namespace videocapturemodule -diff --git a/modules/video_capture/video_capture_options.cc b/modules/video_capture/video_capture_options.cc -index 444c23fcbc..203d0a604b 100644 ---- a/modules/video_capture/video_capture_options.cc -+++ b/modules/video_capture/video_capture_options.cc -@@ -33,7 +33,7 @@ void VideoCaptureOptions::Init(Callback* callback) { - if (allow_pipewire_) { - pipewire_session_ = - rtc::make_ref_counted(); -- pipewire_session_->Init(callback); -+ pipewire_session_->Init(callback, pipewire_fd_); - return; - } - #endif -diff --git a/modules/video_capture/video_capture_options.h b/modules/video_capture/video_capture_options.h -index f35c6142b6..c90e035f37 100644 ---- a/modules/video_capture/video_capture_options.h -+++ b/modules/video_capture/video_capture_options.h -@@ -21,8 +21,7 @@ class PipeWireSession; - } - #endif - --// An object that stores initialization parameters for screen and window --// capturers. -+// An object that stores initialization parameters for video capturers - class RTC_EXPORT VideoCaptureOptions { - public: - VideoCaptureOptions(); -@@ -60,6 +59,7 @@ class RTC_EXPORT VideoCaptureOptions { - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire() const { return allow_pipewire_; } - void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } -+ void set_pipewire_fd(int fd) { pipewire_fd_ = fd; } - rtc::scoped_refptr pipewire_session(); - #endif - -@@ -69,6 +69,7 @@ class RTC_EXPORT VideoCaptureOptions { - #endif - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire_ = false; -+ int pipewire_fd_ = -1; - rtc::scoped_refptr pipewire_session_; - #endif - }; + ChannelSend::~ChannelSend() { -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0112.patch b/third_party/libwebrtc/moz-patch-stack/0112.patch index bfc8c9d371df0..6cc874b4d3db4 100644 --- a/third_party/libwebrtc/moz-patch-stack/0112.patch +++ b/third_party/libwebrtc/moz-patch-stack/0112.patch @@ -1,33 +1,42 @@ -From: Jan Grulich -Date: Thu, 15 Jun 2023 12:41:00 +0000 -Subject: Bug 1724900: WebRTC backport: PipeWire video capture - set device - unique ID during initialization r=pehrsons,webrtc-reviewers +From: Byron Campen +Date: Thu, 20 Jul 2023 14:24:00 +0000 +Subject: Bug 1838080: Work around a race in + ChannelSendFrameTransformerDelegate. r=pehrsons,webrtc-reviewers -This is a simple backport of an WebRTC upstream change. +This variable can be null when a ChannelSendFrameTransformerDelegate is in use, +because that does an async dispatch to the encoder queue in the handling for +transformed frames. If this is unset while that dispatch is in flight, we +nullptr crash. -Upstream commit: 4beafa38d546ab6c0bb423c12762f0c4568aa5ce - -Differential Revision: https://phabricator.services.mozilla.com/D176626 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/583ba187d9e5e6d5174a728936b7bf6afc5ba326 +Differential Revision: https://phabricator.services.mozilla.com/D180735 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/56555ecee7f36ae73abff1cbbd06807c2b65fc19 --- - modules/video_capture/linux/video_capture_pipewire.cc | 4 ++++ - 1 file changed, 4 insertions(+) + audio/channel_send.cc | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) -diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc -index c1e6aae5ea..99109e00e6 100644 ---- a/modules/video_capture/linux/video_capture_pipewire.cc -+++ b/modules/video_capture/linux/video_capture_pipewire.cc -@@ -62,6 +62,10 @@ int32_t VideoCaptureModulePipeWire::Init(const char* deviceUniqueId) { - - node_id_ = id.value(); +diff --git a/audio/channel_send.cc b/audio/channel_send.cc +index f9283c3a00..8a402ca467 100644 +--- a/audio/channel_send.cc ++++ b/audio/channel_send.cc +@@ -285,12 +285,16 @@ class RtpPacketSenderProxy : public RtpPacketSender { + void EnqueuePackets( + std::vector> packets) override { + MutexLock lock(&mutex_); +- rtp_packet_pacer_->EnqueuePackets(std::move(packets)); ++ if (rtp_packet_pacer_) { ++ rtp_packet_pacer_->EnqueuePackets(std::move(packets)); ++ } + } -+ const int len = strlen(deviceUniqueId); -+ _deviceUniqueId = new (std::nothrow) char[len + 1]; -+ memcpy(_deviceUniqueId, deviceUniqueId, len + 1); -+ - return 0; - } + void RemovePacketsForSsrc(uint32_t ssrc) override { + MutexLock lock(&mutex_); +- rtp_packet_pacer_->RemovePacketsForSsrc(ssrc); ++ if (rtp_packet_pacer_) { ++ rtp_packet_pacer_->RemovePacketsForSsrc(ssrc); ++ } + } + private: -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0113.patch b/third_party/libwebrtc/moz-patch-stack/0113.patch index 809530ddf155c..c2a375c3983ba 100644 --- a/third_party/libwebrtc/moz-patch-stack/0113.patch +++ b/third_party/libwebrtc/moz-patch-stack/0113.patch @@ -1,89 +1,69 @@ -From: Nico Grunbaum -Date: Tue, 20 Jun 2023 16:31:00 +0000 -Subject: Bug 1837667 - avoid calling GetDpiForMonitor on Windows < - 8.1;r=mjf,webrtc-reviewers,pehrsons +From: Byron Campen +Date: Thu, 20 Jul 2023 14:24:00 +0000 +Subject: Bug 1838080: Use the current TaskQueue, instead of the current + thread, to init this. r=pehrsons,webrtc-reviewers -Differential Revision: https://phabricator.services.mozilla.com/D180763 -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/1877c1e6db6f8a23c52ab9238c7f62d0b696f0ce +There are situations where the current thread is not set, but the current +TaskQueue is (but not vice versa). + +Differential Revision: https://phabricator.services.mozilla.com/D180736 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/62e71a2f745c4b98d5ee7ce9e6386aa1b657be9b --- - .../win/screen_capture_utils.cc | 33 +++++++++++++++---- - 1 file changed, 26 insertions(+), 7 deletions(-) + .../rtp_video_stream_receiver_frame_transformer_delegate.cc | 3 +-- + .../rtp_video_stream_receiver_frame_transformer_delegate.h | 5 ++--- + video/rtp_video_stream_receiver2.cc | 2 +- + 3 files changed, 4 insertions(+), 6 deletions(-) -diff --git a/modules/desktop_capture/win/screen_capture_utils.cc b/modules/desktop_capture/win/screen_capture_utils.cc -index c0144b0ef3..a5b0fc597c 100644 ---- a/modules/desktop_capture/win/screen_capture_utils.cc -+++ b/modules/desktop_capture/win/screen_capture_utils.cc -@@ -10,14 +10,17 @@ - - #include "modules/desktop_capture/win/screen_capture_utils.h" - -+#include - #include - #include -+#include - - #include - #include - - #include "modules/desktop_capture/desktop_capturer.h" - #include "modules/desktop_capture/desktop_geometry.h" -+#include "mozilla/WindowsVersion.h" // See Bug 1837647 - #include "rtc_base/checks.h" - #include "rtc_base/logging.h" - #include "rtc_base/string_utils.h" -@@ -25,6 +28,28 @@ +diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +index 6e915bf758..ba26b391fe 100644 +--- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc ++++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +@@ -74,8 +74,7 @@ RtpVideoStreamReceiverFrameTransformerDelegate:: + RtpVideoStreamReceiverFrameTransformerDelegate( + RtpVideoFrameReceiver* receiver, + rtc::scoped_refptr frame_transformer, +- rtc::Thread* network_thread, +- uint32_t ssrc) ++ TaskQueueBase* network_thread, uint32_t ssrc) + : receiver_(receiver), + frame_transformer_(std::move(frame_transformer)), + network_thread_(network_thread), +diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.h b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.h +index 3e8257f906..5adca0634c 100644 +--- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.h ++++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.h +@@ -39,8 +39,7 @@ class RtpVideoStreamReceiverFrameTransformerDelegate + RtpVideoStreamReceiverFrameTransformerDelegate( + RtpVideoFrameReceiver* receiver, + rtc::scoped_refptr frame_transformer, +- rtc::Thread* network_thread, +- uint32_t ssrc); ++ TaskQueueBase* network_thread, uint32_t ssrc); - namespace webrtc { + void Init(); + void Reset(); +@@ -65,7 +64,7 @@ class RtpVideoStreamReceiverFrameTransformerDelegate + RtpVideoFrameReceiver* receiver_ RTC_GUARDED_BY(network_sequence_checker_); + rtc::scoped_refptr frame_transformer_ + RTC_GUARDED_BY(network_sequence_checker_); +- rtc::Thread* const network_thread_; ++ TaskQueueBase* const network_thread_; + const uint32_t ssrc_; + }; -+// See Bug 1837647 - upstream commit 60795e8c7a added a method using -+// ::GetDpiForMonitor which is not available on Win7 machines. For Win7, -+// fail as to provoke it to get the system DPI. -+HRESULT TryGetDpiForMonitor(HMONITOR hmonitor, -+ MONITOR_DPI_TYPE dpiType, -+ UINT* dpiX, -+ UINT* dpiY) { -+ static HRESULT (*plat_fn)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); -+ // Grab a pointer to ::GetDpiForMonitor if that has been loaded. -+ // It is available in Windows 8.1 and up. Can we drop the version check? It -+ // would make upstreaming easier. -+ if (!plat_fn) { -+ if (auto* module = ::GetModuleHandle(L"Shcore.dll"); module) { -+ plat_fn = reinterpret_cast( -+ ::GetProcAddress(module, "GetDpiForMonitor")); -+ } -+ } -+ // Call the function we got or return a failure value in the case that -+ // we didn't manage to get a pointer to ::GetDpiForMonitor -+ return plat_fn ? ((*plat_fn)(hmonitor, dpiType, dpiX, dpiY)) : -1; -+} -+ - bool HasActiveDisplay() { - DesktopCapturer::SourceList screens; - -@@ -147,14 +172,9 @@ DesktopRect GetFullscreenRect() { - } - - DesktopVector GetDpiForMonitor(HMONITOR monitor) { --// See Bug 1837647 - upstream commit 60795e8c7a added this method using --// ::GetDpiForMonitor which is not available on Win7 machines. For now, --// we'll return the default case of {96, 96} until we can properly --// restore the functionality for newer machines (See Bug 1837667). --#if 0 - UINT dpi_x, dpi_y; - // MDT_EFFECTIVE_DPI includes the scale factor as well as the system DPI. -- HRESULT hr = ::GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); -+ HRESULT hr = TryGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); - if (SUCCEEDED(hr)) { - return {static_cast(dpi_x), static_cast(dpi_y)}; +diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc +index ec0242e915..c4ec28ee98 100644 +--- a/video/rtp_video_stream_receiver2.cc ++++ b/video/rtp_video_stream_receiver2.cc +@@ -341,7 +341,7 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( + if (frame_transformer) { + frame_transformer_delegate_ = + rtc::make_ref_counted( +- this, std::move(frame_transformer), rtc::Thread::Current(), ++ this, std::move(frame_transformer), TaskQueueBase::Current(), + config_.rtp.remote_ssrc); + frame_transformer_delegate_->Init(); } -@@ -168,7 +188,6 @@ DesktopVector GetDpiForMonitor(HMONITOR monitor) { - ReleaseDC(nullptr, hdc); - return dpi; - } --#endif - - // If everything fails, then return the default DPI for Windows. - return {96, 96}; -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0114.patch b/third_party/libwebrtc/moz-patch-stack/0114.patch index 52dc631cab7aa..c8625e020f97a 100644 --- a/third_party/libwebrtc/moz-patch-stack/0114.patch +++ b/third_party/libwebrtc/moz-patch-stack/0114.patch @@ -1,88 +1,170 @@ -From: Cosmin Sabou -Date: Tue, 20 Jun 2023 21:16:00 +0300 -Subject: Backed out changeset 1877c1e6db6f (bug 1837667) for causing windows - crashes. CLOSED TREE +From: Michael Froman +Date: Thu, 27 Jul 2023 12:42:44 -0500 +Subject: Bug 1838080: Store the rid in TransformableVideoSenderFrame. + r=ng,webrtc-reviewers -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/bdf8893a3dfdac6fe0ad445625a24e6d18e89fda +This is necessary to reliably detect what rid a given keyframe is for, for the +purposes of resolving promises from RTCRtpScriptTransformer.generateKeyFrame. + +Differential Revision: https://phabricator.services.mozilla.com/D180737 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/2f1a0ba74bf71cfa0bc4e77714b8a5276a70cc36 --- - .../win/screen_capture_utils.cc | 33 ++++--------------- - 1 file changed, 7 insertions(+), 26 deletions(-) + api/frame_transformer_interface.h | 1 + + modules/rtp_rtcp/source/rtp_sender.h | 4 ++++ + modules/rtp_rtcp/source/rtp_sender_video.cc | 1 + + ...tp_sender_video_frame_transformer_delegate.cc | 16 +++++++++++----- + ...rtp_sender_video_frame_transformer_delegate.h | 2 ++ + ...stream_receiver_frame_transformer_delegate.cc | 5 +++++ + 6 files changed, 24 insertions(+), 5 deletions(-) -diff --git a/modules/desktop_capture/win/screen_capture_utils.cc b/modules/desktop_capture/win/screen_capture_utils.cc -index a5b0fc597c..c0144b0ef3 100644 ---- a/modules/desktop_capture/win/screen_capture_utils.cc -+++ b/modules/desktop_capture/win/screen_capture_utils.cc -@@ -10,17 +10,14 @@ +diff --git a/api/frame_transformer_interface.h b/api/frame_transformer_interface.h +index 2f7b139f9f..43fedd8595 100644 +--- a/api/frame_transformer_interface.h ++++ b/api/frame_transformer_interface.h +@@ -57,6 +57,7 @@ class TransformableVideoFrameInterface : public TransformableFrameInterface { + public: + virtual ~TransformableVideoFrameInterface() = default; + virtual bool IsKeyFrame() const = 0; ++ virtual const std::string& GetRid() const = 0; - #include "modules/desktop_capture/win/screen_capture_utils.h" + virtual VideoFrameMetadata Metadata() const = 0; --#include - #include - #include --#include +diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h +index fb6c8001f0..70a5c773ab 100644 +--- a/modules/rtp_rtcp/source/rtp_sender.h ++++ b/modules/rtp_rtcp/source/rtp_sender.h +@@ -140,6 +140,10 @@ class RTPSender { - #include - #include + uint32_t SSRC() const RTC_LOCKS_EXCLUDED(send_mutex_) { return ssrc_; } - #include "modules/desktop_capture/desktop_capturer.h" - #include "modules/desktop_capture/desktop_geometry.h" --#include "mozilla/WindowsVersion.h" // See Bug 1837647 - #include "rtc_base/checks.h" - #include "rtc_base/logging.h" - #include "rtc_base/string_utils.h" -@@ -28,28 +25,6 @@ ++ const std::string& Rid() const RTC_LOCKS_EXCLUDED(send_mutex_) { ++ return rid_; ++ } ++ + absl::optional FlexfecSsrc() const RTC_LOCKS_EXCLUDED(send_mutex_) { + return flexfec_ssrc_; + } +diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc +index c863db4ccf..adc53d2243 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_video.cc ++++ b/modules/rtp_rtcp/source/rtp_sender_video.cc +@@ -169,6 +169,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config) + config.frame_transformer, + rtp_sender_->SSRC(), + rtp_sender_->Csrcs(), ++ rtp_sender_->Rid(), + config.task_queue_factory) + : nullptr) { + if (frame_transformer_delegate_) +diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +index 34b4af0ec9..71f7db6f70 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc ++++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +@@ -31,7 +31,8 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { + uint32_t rtp_timestamp, + absl::optional expected_retransmission_time_ms, + uint32_t ssrc, +- std::vector csrcs) ++ std::vector csrcs, ++ const std::string& rid) + : encoded_data_(encoded_image.GetEncodedData()), + header_(video_header), + frame_type_(encoded_image._frameType), +@@ -42,7 +43,8 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { + capture_time_identifier_(encoded_image.CaptureTimeIdentifier()), + expected_retransmission_time_ms_(expected_retransmission_time_ms), + ssrc_(ssrc), +- csrcs_(csrcs) { ++ csrcs_(csrcs), ++ rid_(rid) { + RTC_DCHECK_GE(payload_type_, 0); + RTC_DCHECK_LE(payload_type_, 127); + } +@@ -92,6 +94,8 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { - namespace webrtc { + Direction GetDirection() const override { return Direction::kSender; } --// See Bug 1837647 - upstream commit 60795e8c7a added a method using --// ::GetDpiForMonitor which is not available on Win7 machines. For Win7, --// fail as to provoke it to get the system DPI. --HRESULT TryGetDpiForMonitor(HMONITOR hmonitor, -- MONITOR_DPI_TYPE dpiType, -- UINT* dpiX, -- UINT* dpiY) { -- static HRESULT (*plat_fn)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); -- // Grab a pointer to ::GetDpiForMonitor if that has been loaded. -- // It is available in Windows 8.1 and up. Can we drop the version check? It -- // would make upstreaming easier. -- if (!plat_fn) { -- if (auto* module = ::GetModuleHandle(L"Shcore.dll"); module) { -- plat_fn = reinterpret_cast( -- ::GetProcAddress(module, "GetDpiForMonitor")); -- } -- } -- // Call the function we got or return a failure value in the case that -- // we didn't manage to get a pointer to ::GetDpiForMonitor -- return plat_fn ? ((*plat_fn)(hmonitor, dpiType, dpiX, dpiY)) : -1; --} -- - bool HasActiveDisplay() { - DesktopCapturer::SourceList screens; ++ const std::string& GetRid() const override { return rid_; } ++ + private: + rtc::scoped_refptr encoded_data_; + RTPVideoHeader header_; +@@ -105,6 +109,7 @@ class TransformableVideoSenderFrame : public TransformableVideoFrameInterface { -@@ -172,9 +147,14 @@ DesktopRect GetFullscreenRect() { + uint32_t ssrc_; + std::vector csrcs_; ++ const std::string rid_; + }; + } // namespace + +@@ -113,11 +118,12 @@ RTPSenderVideoFrameTransformerDelegate::RTPSenderVideoFrameTransformerDelegate( + rtc::scoped_refptr frame_transformer, + uint32_t ssrc, + std::vector csrcs, ++ const std::string& rid, + TaskQueueFactory* task_queue_factory) + : sender_(sender), + frame_transformer_(std::move(frame_transformer)), + ssrc_(ssrc), +- csrcs_(csrcs), ++ rid_(rid), + transformation_queue_(task_queue_factory->CreateTaskQueue( + "video_frame_transformer", + TaskQueueFactory::Priority::NORMAL)) {} +@@ -136,7 +142,7 @@ bool RTPSenderVideoFrameTransformerDelegate::TransformFrame( + absl::optional expected_retransmission_time_ms) { + frame_transformer_->Transform(std::make_unique( + encoded_image, video_header, payload_type, codec_type, rtp_timestamp, +- expected_retransmission_time_ms, ssrc_, csrcs_)); ++ expected_retransmission_time_ms, ssrc_, csrcs_, rid_)); + return true; } - DesktopVector GetDpiForMonitor(HMONITOR monitor) { -+// See Bug 1837647 - upstream commit 60795e8c7a added this method using -+// ::GetDpiForMonitor which is not available on Win7 machines. For now, -+// we'll return the default case of {96, 96} until we can properly -+// restore the functionality for newer machines (See Bug 1837667). -+#if 0 - UINT dpi_x, dpi_y; - // MDT_EFFECTIVE_DPI includes the scale factor as well as the system DPI. -- HRESULT hr = TryGetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); -+ HRESULT hr = ::GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); - if (SUCCEEDED(hr)) { - return {static_cast(dpi_x), static_cast(dpi_y)}; - } -@@ -188,6 +168,7 @@ DesktopVector GetDpiForMonitor(HMONITOR monitor) { - ReleaseDC(nullptr, hdc); - return dpi; +@@ -215,7 +221,7 @@ std::unique_ptr CloneSenderVideoFrame( + encoded_image, new_header, original->GetPayloadType(), new_header.codec, + original->GetTimestamp(), + absl::nullopt, // expected_retransmission_time_ms +- original->GetSsrc(), metadata.GetCsrcs()); ++ original->GetSsrc(), metadata.GetCsrcs(), original->GetRid()); + } + + } // namespace webrtc +diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h +index a397041811..83a475dc72 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h ++++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h +@@ -57,6 +57,7 @@ class RTPSenderVideoFrameTransformerDelegate : public TransformedFrameCallback { + rtc::scoped_refptr frame_transformer, + uint32_t ssrc, + std::vector csrcs, ++ const std::string& rid, + TaskQueueFactory* send_transport_queue); + + void Init(); +@@ -104,6 +105,7 @@ class RTPSenderVideoFrameTransformerDelegate : public TransformedFrameCallback { + rtc::scoped_refptr frame_transformer_; + const uint32_t ssrc_; + std::vector csrcs_; ++ const std::string rid_; + // Used when the encoded frames arrives without a current task queue. This can + // happen if a hardware encoder was used. + std::unique_ptr transformation_queue_; +diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +index ba26b391fe..71e58eab24 100644 +--- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc ++++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate.cc +@@ -51,6 +51,11 @@ class TransformableVideoReceiverFrame + return frame_->FrameType() == VideoFrameType::kVideoFrameKey; } -+#endif - // If everything fails, then return the default DPI for Windows. - return {96, 96}; ++ const std::string& GetRid() const override { ++ static const std::string empty; ++ return empty; ++ } ++ + VideoFrameMetadata Metadata() const override { return metadata_; } + + void SetMetadata(const VideoFrameMetadata&) override { -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0115.patch b/third_party/libwebrtc/moz-patch-stack/0115.patch index 714b8965458b3..b6ded291ad985 100644 --- a/third_party/libwebrtc/moz-patch-stack/0115.patch +++ b/third_party/libwebrtc/moz-patch-stack/0115.patch @@ -1,32 +1,41 @@ -From: Jan-Ivar Bruaroey -Date: Wed, 28 Jun 2023 20:45:00 -0400 -Subject: Bug 1839451 - (fix-0f43da2248) Keep mozilla's - RTCPReceiver::RemoteRTCPSenderInfo function working. +From: Byron Campen +Date: Thu, 20 Jul 2023 14:24:00 +0000 +Subject: Bug 1838080: Ensure that last ref to transformation_queue_ is not + released on itself. r=pehrsons,webrtc-reviewers -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/154c9cdb386d0f50c5e1549270e1af6ab4969602 +Differential Revision: https://phabricator.services.mozilla.com/D181699 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/91d9e8b6a5c430a73561ffd2330865f04fcb1a6d --- - modules/rtp_rtcp/source/rtcp_receiver.cc | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) + .../rtp_sender_video_frame_transformer_delegate.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) -diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc -index e00761726c..3cbbb915fe 100644 ---- a/modules/rtp_rtcp/source/rtcp_receiver.cc -+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc -@@ -399,10 +399,10 @@ void RTCPReceiver::RemoteRTCPSenderInfo(uint32_t* packet_count, - int64_t* ntp_timestamp_ms, - int64_t* remote_ntp_timestamp_ms) const { - MutexLock lock(&rtcp_receiver_lock_); -- *packet_count = remote_sender_packet_count_; -- *octet_count = remote_sender_octet_count_; -- *ntp_timestamp_ms = last_received_sr_ntp_.ToMs(); -- *remote_ntp_timestamp_ms = remote_sender_ntp_time_.ToMs(); -+ *packet_count = remote_sender_.packets_sent; -+ *octet_count = remote_sender_.bytes_sent; -+ *ntp_timestamp_ms = remote_sender_.last_arrival_timestamp.ToMs(); -+ *remote_ntp_timestamp_ms = remote_sender_.last_remote_timestamp.ToMs(); +diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +index 71f7db6f70..79ceae5209 100644 +--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc ++++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc +@@ -17,6 +17,7 @@ + #include "api/task_queue/task_queue_factory.h" + #include "modules/rtp_rtcp/source/rtp_descriptor_authentication.h" + #include "rtc_base/checks.h" ++#include "rtc_base/event.h" + + namespace webrtc { + namespace { +@@ -202,6 +203,14 @@ void RTPSenderVideoFrameTransformerDelegate::Reset() { + MutexLock lock(&sender_lock_); + sender_ = nullptr; + } ++ // Wait until all pending tasks are executed, to ensure that the last ref ++ // standing is not on the transformation queue. ++ rtc::Event flush; ++ transformation_queue_->PostTask([this, &flush]() { ++ RTC_DCHECK_RUN_ON(transformation_queue_.get()); ++ flush.Set(); ++ }); ++ flush.Wait(rtc::Event::kForever); } - std::vector RTCPReceiver::GetLatestReportBlockData() const { + std::unique_ptr CloneSenderVideoFrame( -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0116.patch b/third_party/libwebrtc/moz-patch-stack/0116.patch index b19791538d32c..5fd40988b4962 100644 --- a/third_party/libwebrtc/moz-patch-stack/0116.patch +++ b/third_party/libwebrtc/moz-patch-stack/0116.patch @@ -1,26 +1,49 @@ -From: Jan-Ivar Bruaroey -Date: Fri, 30 Jun 2023 12:20:00 -0400 -Subject: Bug 1839451 - (fix-f6eae959bf) - s/rtc_encoder_simulcast_proxy/rtc_simulcast_encoder_adapter/ BUILD ref. +From: Jan Grulich +Date: Thu, 27 Jul 2023 09:49:00 +0000 +Subject: Bug 1841851 - WebRTC backport: PipeWire capturer: increase buffer + size to avoid buffer overflow r=jib,webrtc-reviewers,mjf -Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/876b3f5821cd5c30564a82c1da7d057d79d17b01 +This is a simple backport of an WebRTC upstream change. + +Upstream commit: 8fcc6df79daf1810cd4ecdb8d2ef1d361abfdc9c + +Differential Revision: https://phabricator.services.mozilla.com/D183355 +Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/263be02fdeb0c3556e1da296eb18eb3d154eb99e --- - BUILD.gn | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + .../linux/wayland/shared_screencast_stream.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/BUILD.gn b/BUILD.gn -index 0f39264f56..6eb14773b0 100644 ---- a/BUILD.gn -+++ b/BUILD.gn -@@ -560,7 +560,7 @@ if (!build_with_chromium) { - deps += [ - "api/video_codecs:video_codecs_api", - "api/video_codecs:rtc_software_fallback_wrappers", -- "media:rtc_encoder_simulcast_proxy", -+ "media:rtc_simulcast_encoder_adapter", - "modules/video_coding:webrtc_vp8", - "modules/video_coding:webrtc_vp9", - ] +diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +index 17c895088a..0102346036 100644 +--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc ++++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +@@ -281,7 +281,7 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged( + + that->stream_size_ = DesktopSize(width, height); + +- uint8_t buffer[1024] = {}; ++ uint8_t buffer[2048] = {}; + auto builder = spa_pod_builder{buffer, sizeof(buffer)}; + + // Setup buffers and meta header for new format. +@@ -364,7 +364,7 @@ void SharedScreenCastStreamPrivate::OnRenegotiateFormat(void* data, uint64_t) { + { + PipeWireThreadLoopLock thread_loop_lock(that->pw_main_loop_); + +- uint8_t buffer[2048] = {}; ++ uint8_t buffer[4096] = {}; + + spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; + +@@ -482,7 +482,7 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( + + pw_stream_add_listener(pw_stream_, &spa_stream_listener_, + &pw_stream_events_, this); +- uint8_t buffer[2048] = {}; ++ uint8_t buffer[4096] = {}; + + spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; + -- 2.34.1 diff --git a/third_party/libwebrtc/moz-patch-stack/0f87b38535.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/0f87b38535.no-op-cherry-pick-msg deleted file mode 100644 index 157e95cb7ce05..0000000000000 --- a/third_party/libwebrtc/moz-patch-stack/0f87b38535.no-op-cherry-pick-msg +++ /dev/null @@ -1 +0,0 @@ -We cherry-picked this in bug 1832717 diff --git a/third_party/libwebrtc/moz-patch-stack/4beafa38d5.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/4beafa38d5.no-op-cherry-pick-msg deleted file mode 100644 index 902911ad7b054..0000000000000 --- a/third_party/libwebrtc/moz-patch-stack/4beafa38d5.no-op-cherry-pick-msg +++ /dev/null @@ -1 +0,0 @@ -We cherry-picked this in bug 1724900 diff --git a/third_party/libwebrtc/moz-patch-stack/ba41b40461.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/ba41b40461.no-op-cherry-pick-msg deleted file mode 100644 index d5186fa72455d..0000000000000 --- a/third_party/libwebrtc/moz-patch-stack/ba41b40461.no-op-cherry-pick-msg +++ /dev/null @@ -1 +0,0 @@ -We cherry-picked this in Bug 1810949. diff --git a/third_party/libwebrtc/moz-patch-stack/d75b9e9ff07ee42841b4e416629c9fbd4b058905.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/d75b9e9ff07ee42841b4e416629c9fbd4b058905.no-op-cherry-pick-msg deleted file mode 100644 index abbd9e1035387..0000000000000 --- a/third_party/libwebrtc/moz-patch-stack/d75b9e9ff07ee42841b4e416629c9fbd4b058905.no-op-cherry-pick-msg +++ /dev/null @@ -1 +0,0 @@ -We already cherry-picked this when we vendored df36242372f039853fa5f1bcd8407b90230b448b. diff --git a/third_party/libwebrtc/net/dcsctp/packet/BUILD.gn b/third_party/libwebrtc/net/dcsctp/packet/BUILD.gn index 08bdb0f5a533c..7abccc004bb80 100644 --- a/third_party/libwebrtc/net/dcsctp/packet/BUILD.gn +++ b/third_party/libwebrtc/net/dcsctp/packet/BUILD.gn @@ -98,6 +98,8 @@ rtc_library("parameter") { "parameter/state_cookie_parameter.h", "parameter/supported_extensions_parameter.cc", "parameter/supported_extensions_parameter.h", + "parameter/zero_checksum_acceptable_chunk_parameter.cc", + "parameter/zero_checksum_acceptable_chunk_parameter.h", ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", @@ -323,6 +325,7 @@ if (rtc_include_tests) { "parameter/ssn_tsn_reset_request_parameter_test.cc", "parameter/state_cookie_parameter_test.cc", "parameter/supported_extensions_parameter_test.cc", + "parameter/zero_checksum_acceptable_chunk_parameter_test.cc", "sctp_packet_test.cc", "tlv_trait_test.cc", ] diff --git a/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc new file mode 100644 index 0000000000000..75f7d3c4871d0 --- /dev/null +++ b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 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 "net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h" + +#include + +#include + +#include "absl/types/optional.h" +#include "api/array_view.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 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +constexpr int ZeroChecksumAcceptableChunkParameter::kType; + +absl::optional +ZeroChecksumAcceptableChunkParameter::Parse( + rtc::ArrayView data) { + if (!ParseTLV(data).has_value()) { + return absl::nullopt; + } + return ZeroChecksumAcceptableChunkParameter(); +} + +void ZeroChecksumAcceptableChunkParameter::SerializeTo( + std::vector& out) const { + AllocateTLV(out); +} + +std::string ZeroChecksumAcceptableChunkParameter::ToString() const { + return "Zero Checksum Acceptable"; +} +} // namespace dcsctp diff --git a/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h new file mode 100644 index 0000000000000..9ae2ec8280f32 --- /dev/null +++ b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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 NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_ +#define NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_ +#include +#include + +#include +#include + +#include "absl/strings/string_view.h" +#include "api/array_view.h" +#include "net/dcsctp/packet/parameter/parameter.h" +#include "net/dcsctp/packet/tlv_trait.h" + +namespace dcsctp { + +// https://datatracker.ietf.org/doc/draft-tuexen-tsvwg-sctp-zero-checksum/ +struct ZeroChecksumAcceptableChunkParameterConfig : ParameterConfig { + static constexpr int kType = 0x8001; + static constexpr size_t kHeaderSize = 4; + static constexpr size_t kVariableLengthAlignment = 0; +}; + +class ZeroChecksumAcceptableChunkParameter + : public Parameter, + public TLVTrait { + public: + static constexpr int kType = + ZeroChecksumAcceptableChunkParameterConfig::kType; + + ZeroChecksumAcceptableChunkParameter() {} + + static absl::optional Parse( + rtc::ArrayView data); + + void SerializeTo(std::vector& out) const override; + std::string ToString() const override; +}; + +} // namespace dcsctp + +#endif // NET_DCSCTP_PACKET_PARAMETER_ZERO_CHECKSUM_ACCEPTABLE_CHUNK_PARAMETER_H_ diff --git a/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc new file mode 100644 index 0000000000000..8a004e178888f --- /dev/null +++ b/third_party/libwebrtc/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc @@ -0,0 +1,53 @@ +/* + * Copyright (c) 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 "net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h" + +#include + +#include +#include + +#include "net/dcsctp/testing/testing_macros.h" +#include "rtc_base/gunit.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace dcsctp { +namespace { +using ::testing::ElementsAre; + +TEST(ZeroChecksumAcceptableChunkParameterTest, SerializeAndDeserialize) { + ZeroChecksumAcceptableChunkParameter parameter; + + std::vector serialized; + parameter.SerializeTo(serialized); + + EXPECT_THAT(serialized, ElementsAre(0x80, 0x01, 0x00, 0x04)); + + ASSERT_HAS_VALUE_AND_ASSIGN( + ZeroChecksumAcceptableChunkParameter deserialized, + ZeroChecksumAcceptableChunkParameter::Parse(serialized)); +} + +TEST(ZeroChecksumAcceptableChunkParameterTest, FailToDeserialize) { + std::vector invalid = {0x00, 0x00, 0x00, 0x00}; + + EXPECT_FALSE( + ZeroChecksumAcceptableChunkParameter::Parse(invalid).has_value()); +} + +TEST(ZeroChecksumAcceptableChunkParameterTest, HasToString) { + ZeroChecksumAcceptableChunkParameter parameter; + + EXPECT_EQ(parameter.ToString(), "Zero Checksum Acceptable"); +} + +} // namespace +} // namespace dcsctp diff --git a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.cc b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.cc index cc662351226ee..de407bb4c7f9b 100644 --- a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.cc +++ b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.cc @@ -62,7 +62,7 @@ SctpPacket::Builder& SctpPacket::Builder::Add(const Chunk& chunk) { buffer.Store16<0>(source_port_); buffer.Store16<2>(dest_port_); buffer.Store32<4>(*verification_tag_); - // Checksum is at offset 8 - written when calling Build(); + // Checksum is at offset 8 - written when calling Build(), if configured. } RTC_DCHECK(IsDivisibleBy4(out_.size())); @@ -89,11 +89,11 @@ size_t SctpPacket::Builder::bytes_remaining() const { return max_packet_size_ - out_.size(); } -std::vector SctpPacket::Builder::Build() { +std::vector SctpPacket::Builder::Build(bool write_checksum) { std::vector out; out_.swap(out); - if (!out.empty()) { + if (!out.empty() && write_checksum) { uint32_t crc = GenerateCrc32C(out); BoundedByteWriter(out).Store32<8>(crc); } @@ -105,9 +105,8 @@ std::vector SctpPacket::Builder::Build() { return out; } -absl::optional SctpPacket::Parse( - rtc::ArrayView data, - bool disable_checksum_verification) { +absl::optional SctpPacket::Parse(rtc::ArrayView data, + const DcSctpOptions& options) { if (data.size() < kHeaderSize + kChunkTlvHeaderSize || data.size() > kMaxUdpPacketSize) { RTC_DLOG(LS_WARNING) << "Invalid packet size"; @@ -126,19 +125,28 @@ absl::optional SctpPacket::Parse( std::vector data_copy = std::vector(data.begin(), data.end()); - // Verify the checksum. The checksum field must be zero when that's done. - BoundedByteWriter(data_copy).Store32<8>(0); - uint32_t calculated_checksum = GenerateCrc32C(data_copy); - if (!disable_checksum_verification && - calculated_checksum != common_header.checksum) { - RTC_DLOG(LS_WARNING) << rtc::StringFormat( - "Invalid packet checksum, packet_checksum=0x%08x, " - "calculated_checksum=0x%08x", - common_header.checksum, calculated_checksum); - return absl::nullopt; + if (options.disable_checksum_verification || + (options.enable_zero_checksum && 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 + // checksum value of zero in addition to SCTP packets containing the correct + // CRC32c checksum value for this association. + } else { + // Verify the checksum. The checksum field must be zero when that's done. + BoundedByteWriter(data_copy).Store32<8>(0); + uint32_t calculated_checksum = GenerateCrc32C(data_copy); + if (calculated_checksum != common_header.checksum) { + RTC_DLOG(LS_WARNING) << rtc::StringFormat( + "Invalid packet checksum, packet_checksum=0x%08x, " + "calculated_checksum=0x%08x", + common_header.checksum, calculated_checksum); + return absl::nullopt; + } + // Restore the checksum in the header. + BoundedByteWriter(data_copy).Store32<8>( + common_header.checksum); } - // Restore the checksum in the header. - BoundedByteWriter(data_copy).Store32<8>(common_header.checksum); // Validate and parse the chunk headers in the message. /* diff --git a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.h b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.h index 4c6234e0c9ef3..0d348b448f48b 100644 --- a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.h +++ b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet.h @@ -74,7 +74,9 @@ class SctpPacket { // Returns the payload of the build SCTP packet. The Builder will be cleared // after having called this function, and can be used to build a new packet. - std::vector Build(); + // If `write_checksum` is set to false, a value of zero (0) will be written + // as the packet's checksum, instead of the crc32c value. + std::vector Build(bool write_checksum = true); private: VerificationTag verification_tag_; @@ -87,9 +89,8 @@ class SctpPacket { }; // Parses `data` as an SCTP packet and returns it if it validates. - static absl::optional Parse( - rtc::ArrayView data, - bool disable_checksum_verification = false); + static absl::optional Parse(rtc::ArrayView data, + const DcSctpOptions& options); // Returns the SCTP common header. const CommonHeader& common_header() const { return common_header_; } diff --git a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet_test.cc b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet_test.cc index 7438315eecf38..fcdd161c0d489 100644 --- a/third_party/libwebrtc/net/dcsctp/packet/sctp_packet_test.cc +++ b/third_party/libwebrtc/net/dcsctp/packet/sctp_packet_test.cc @@ -32,9 +32,13 @@ namespace dcsctp { namespace { +using ::testing::ElementsAre; using ::testing::SizeIs; constexpr VerificationTag kVerificationTag = VerificationTag(0x12345678); +constexpr DcSctpOptions kVerifyChecksumOptions = + DcSctpOptions{.disable_checksum_verification = false, + .enable_zero_checksum = false}; TEST(SctpPacketTest, DeserializeSimplePacketFromCapture) { /* @@ -87,7 +91,8 @@ TEST(SctpPacketTest, DeserializeSimplePacketFromCapture) { 0x68, 0x2a, 0xc2, 0x97, 0x80, 0x04, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x06, 0x80, 0xc1, 0x00, 0x00}; - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(data)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(data, kVerifyChecksumOptions)); EXPECT_EQ(packet.common_header().source_port, 5000); EXPECT_EQ(packet.common_header().destination_port, 5000); EXPECT_EQ(packet.common_header().verification_tag, VerificationTag(0)); @@ -130,7 +135,8 @@ TEST(SctpPacketTest, DeserializePacketWithTwoChunks) { 0x03, 0x00, 0x00, 0x10, 0xae, 0xa9, 0x52, 0x52, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(data)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(data, kVerifyChecksumOptions)); EXPECT_EQ(packet.common_header().source_port, 1234); EXPECT_EQ(packet.common_header().destination_port, 4321); EXPECT_EQ(packet.common_header().verification_tag, @@ -172,7 +178,7 @@ TEST(SctpPacketTest, DeserializePacketWithWrongChecksum) { 0xf5, 0x31, 0x03, 0x00, 0x00, 0x10, 0x55, 0x08, 0x36, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - EXPECT_FALSE(SctpPacket::Parse(data).has_value()); + EXPECT_FALSE(SctpPacket::Parse(data, kVerifyChecksumOptions).has_value()); } TEST(SctpPacketTest, DeserializePacketDontValidateChecksum) { @@ -202,7 +208,8 @@ TEST(SctpPacketTest, DeserializePacketDontValidateChecksum) { ASSERT_HAS_VALUE_AND_ASSIGN( SctpPacket packet, - SctpPacket::Parse(data, /*disable_checksum_verification=*/true)); + SctpPacket::Parse(data, {.disable_checksum_verification = true, + .enable_zero_checksum = false})); EXPECT_EQ(packet.common_header().source_port, 5000); EXPECT_EQ(packet.common_header().destination_port, 5000); EXPECT_EQ(packet.common_header().verification_tag, @@ -220,7 +227,8 @@ TEST(SctpPacketTest, SerializeAndDeserializeSingleChunk) { b.Add(init); std::vector serialized = b.Build(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(serialized)); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, SctpPacket::Parse(serialized, kVerifyChecksumOptions)); EXPECT_EQ(packet.common_header().verification_tag, kVerificationTag); @@ -250,7 +258,8 @@ TEST(SctpPacketTest, SerializeAndDeserializeThreeChunks) { std::vector serialized = b.Build(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(serialized)); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, SctpPacket::Parse(serialized, kVerifyChecksumOptions)); EXPECT_EQ(packet.common_header().verification_tag, kVerificationTag); @@ -279,7 +288,8 @@ TEST(SctpPacketTest, ParseAbortWithEmptyCause) { /*filled_in_verification_tag=*/true, Parameters::Builder().Add(UserInitiatedAbortCause("")).Build())); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(b.Build())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, SctpPacket::Parse(b.Build(), kVerifyChecksumOptions)); EXPECT_EQ(packet.common_header().verification_tag, kVerificationTag); @@ -298,7 +308,7 @@ TEST(SctpPacketTest, DetectPacketWithZeroSizeChunk) { uint8_t data[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x0a, 0x0a, 0x5c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00}; - EXPECT_FALSE(SctpPacket::Parse(data, true).has_value()); + EXPECT_FALSE(SctpPacket::Parse(data, kVerifyChecksumOptions).has_value()); } TEST(SctpPacketTest, ReturnsCorrectSpaceAvailableToStayWithinMTU) { @@ -338,5 +348,95 @@ TEST(SctpPacketTest, ReturnsCorrectSpaceAvailableToStayWithinMTU) { EXPECT_EQ(builder.bytes_remaining(), 0u); // Hand-calculated. } +TEST(SctpPacketTest, AcceptsZeroSetZeroChecksum) { + /* + Stream Control Transmission Protocol, Src Port: 5000 (5000), + Dst Port: 5000 (5000) + Source port: 5000 + Destination port: 5000 + Verification tag: 0x0eddca08 + [Association index: 1] + Checksum: 0x00000000 [unverified] + [Checksum Status: Unverified] + SACK chunk (Cumulative TSN: 1426601536, a_rwnd: 131072, + gaps: 0, duplicate TSNs: 0) + Chunk type: SACK (3) + Chunk flags: 0x00 + Chunk length: 16 + Cumulative TSN ACK: 1426601536 + Advertised receiver window credit (a_rwnd): 131072 + Number of gap acknowledgement blocks: 0 + Number of duplicated TSNs: 0 + */ + + uint8_t data[] = {0x13, 0x88, 0x13, 0x88, 0x0e, 0xdd, 0xca, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x10, 0x55, 0x08, 0x36, 0x40, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, + SctpPacket::Parse(data, {.disable_checksum_verification = false, + .enable_zero_checksum = true})); + EXPECT_EQ(packet.common_header().source_port, 5000); + EXPECT_EQ(packet.common_header().destination_port, 5000); + EXPECT_EQ(packet.common_header().verification_tag, + VerificationTag(0x0eddca08u)); + EXPECT_EQ(packet.common_header().checksum, 0x00000000u); +} + +TEST(SctpPacketTest, RejectsNonZeroIncorrectChecksumWhenZeroChecksumIsActive) { + /* + Stream Control Transmission Protocol, Src Port: 5000 (5000), + Dst Port: 5000 (5000) + Source port: 5000 + Destination port: 5000 + Verification tag: 0x0eddca08 + [Association index: 1] + Checksum: 0x00000001 [unverified] + [Checksum Status: Unverified] + SACK chunk (Cumulative TSN: 1426601536, a_rwnd: 131072, + gaps: 0, duplicate TSNs: 0) + Chunk type: SACK (3) + Chunk flags: 0x00 + Chunk length: 16 + Cumulative TSN ACK: 1426601536 + Advertised receiver window credit (a_rwnd): 131072 + Number of gap acknowledgement blocks: 0 + Number of duplicated TSNs: 0 + */ + + uint8_t data[] = {0x13, 0x88, 0x13, 0x88, 0x0e, 0xdd, 0xca, 0x08, 0x01, 0x00, + 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()); +} + +TEST(SctpPacketTest, WritePacketWithCalculatedChecksum) { + SctpPacket::Builder b(kVerificationTag, {}); + b.Add(SackChunk(/*cumulative_tsn_ack=*/TSN(999), /*a_rwnd=*/456, + /*gap_ack_blocks=*/{}, + /*duplicate_tsns=*/{})); + EXPECT_THAT(b.Build(), + ElementsAre(0x13, 0x88, 0x13, 0x88, 0x12, 0x34, 0x56, 0x78, // + 0x07, 0xe8, 0x38, 0x77, // checksum + 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0xe7, 0x00, + 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x00)); +} + +TEST(SctpPacketTest, WritePacketWithZeroChecksum) { + SctpPacket::Builder b(kVerificationTag, {}); + b.Add(SackChunk(/*cumulative_tsn_ack=*/TSN(999), /*a_rwnd=*/456, + /*gap_ack_blocks=*/{}, + /*duplicate_tsns=*/{})); + EXPECT_THAT(b.Build(/*write_checksum=*/false), + ElementsAre(0x13, 0x88, 0x13, 0x88, 0x12, 0x34, 0x56, 0x78, // + 0x00, 0x00, 0x00, 0x00, // checksum + 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0xe7, 0x00, + 0x00, 0x01, 0xc8, 0x00, 0x00, 0x00, 0x00)); +} + } // namespace } // namespace dcsctp diff --git a/third_party/libwebrtc/net/dcsctp/public/dcsctp_handover_state.h b/third_party/libwebrtc/net/dcsctp/public/dcsctp_handover_state.h index 253f4da93944f..f277ebc02c56b 100644 --- a/third_party/libwebrtc/net/dcsctp/public/dcsctp_handover_state.h +++ b/third_party/libwebrtc/net/dcsctp/public/dcsctp_handover_state.h @@ -40,6 +40,7 @@ struct DcSctpSocketHandoverState { bool partial_reliability = false; bool message_interleaving = false; bool reconfig = false; + bool zero_checksum = false; uint16_t negotiated_maximum_incoming_streams = 0; uint16_t negotiated_maximum_outgoing_streams = 0; }; diff --git a/third_party/libwebrtc/net/dcsctp/public/dcsctp_options.h b/third_party/libwebrtc/net/dcsctp/public/dcsctp_options.h index 4511bed4a4a85..d19798054c204 100644 --- a/third_party/libwebrtc/net/dcsctp/public/dcsctp_options.h +++ b/third_party/libwebrtc/net/dcsctp/public/dcsctp_options.h @@ -193,8 +193,17 @@ struct DcSctpOptions { // If RTO should be added to heartbeat_interval bool heartbeat_interval_include_rtt = true; - // Disables SCTP packet crc32 verification. Useful when running with fuzzers. + // 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; }; } // namespace dcsctp diff --git a/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn b/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn index 92ce413d0d96a..aeb157b56a71f 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn +++ b/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn @@ -225,6 +225,7 @@ if (rtc_include_tests) { ":mock_context", ":packet_sender", ":stream_reset_handler", + ":transmission_control_block", "../../../api:array_view", "../../../api:create_network_emulation_manager", "../../../api:network_emulation_manager_api", @@ -273,6 +274,7 @@ if (rtc_include_tests) { "packet_sender_test.cc", "state_cookie_test.cc", "stream_reset_handler_test.cc", + "transmission_control_block_test.cc", ] } } diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc index f831ba090c49f..139ec28055ab7 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc @@ -755,8 +755,7 @@ void DcSctpSocket::ReceivePacket(rtc::ArrayView data) { packet_observer_->OnReceivedPacket(callbacks_.TimeMillis(), data); } - absl::optional packet = - SctpPacket::Parse(data, options_.disable_checksum_verification); + absl::optional packet = SctpPacket::Parse(data, options_); if (!packet.has_value()) { // https://tools.ietf.org/html/rfc4960#section-6.8 // "The default procedure for handling invalid SCTP packets is to @@ -798,7 +797,7 @@ void DcSctpSocket::ReceivePacket(rtc::ArrayView data) { } void DcSctpSocket::DebugPrintOutgoing(rtc::ArrayView payload) { - auto packet = SctpPacket::Parse(payload); + auto packet = SctpPacket::Parse(payload, options_); RTC_DCHECK(packet.has_value()); for (const auto& desc : packet->descriptors()) { diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc index f38624d6061fe..0da893d9bdf20 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc @@ -67,9 +67,10 @@ constexpr SendOptions kSendOptions; constexpr size_t kLargeMessageSize = DcSctpOptions::kMaxSafeMTUSize * 20; constexpr size_t kSmallMessageSize = 10; constexpr int kMaxBurstPackets = 4; +constexpr DcSctpOptions kDefaultOptions; MATCHER_P(HasDataChunkWithStreamId, stream_id, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -96,7 +97,7 @@ MATCHER_P(HasDataChunkWithStreamId, stream_id, "") { } MATCHER_P(HasDataChunkWithPPID, ppid, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -123,7 +124,7 @@ MATCHER_P(HasDataChunkWithPPID, ppid, "") { } MATCHER_P(HasDataChunkWithSsn, ssn, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -150,7 +151,7 @@ MATCHER_P(HasDataChunkWithSsn, ssn, "") { } MATCHER_P(HasDataChunkWithMid, mid, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -177,7 +178,7 @@ MATCHER_P(HasDataChunkWithMid, mid, "") { } MATCHER_P(HasSackWithCumAckTsn, tsn, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -204,7 +205,7 @@ MATCHER_P(HasSackWithCumAckTsn, tsn, "") { } MATCHER(HasSackWithNoGapAckBlocks, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -231,7 +232,7 @@ MATCHER(HasSackWithNoGapAckBlocks, "") { } MATCHER_P(HasReconfigWithStreams, streams_matcher, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -269,7 +270,7 @@ MATCHER_P(HasReconfigWithStreams, streams_matcher, "") { } MATCHER_P(HasReconfigWithResponse, result, "") { - absl::optional packet = SctpPacket::Parse(arg); + absl::optional packet = SctpPacket::Parse(arg, kDefaultOptions); if (!packet.has_value()) { *result_listener << "data didn't parse as an SctpPacket"; return false; @@ -328,7 +329,7 @@ std::unique_ptr GetPacketObserver(absl::string_view name) { struct SocketUnderTest { explicit SocketUnderTest(absl::string_view name, - const DcSctpOptions& opts = {}) + const DcSctpOptions& opts = kDefaultOptions) : options(FixupOptions(opts)), cb(name), socket(name, cb, GetPacketObserver(name), options) {} @@ -628,8 +629,9 @@ TEST(DcSctpSocketTest, ResendInitAndEstablishConnection) { a.socket.Connect(); // INIT is never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(init_packet.descriptors()[0].type, InitChunk::kType); AdvanceTime(a, z, a.options.t1_init_timeout); @@ -654,16 +656,18 @@ TEST(DcSctpSocketTest, ResendingInitTooManyTimesAborts) { a.socket.Connect(); // INIT is never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(init_packet.descriptors()[0].type, InitChunk::kType); for (int i = 0; i < *a.options.max_init_retransmits; ++i) { AdvanceTime(a, z, a.options.t1_init_timeout * (1 << i)); // INIT is resent - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket resent_init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket resent_init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(resent_init_packet.descriptors()[0].type, InitChunk::kType); } @@ -687,8 +691,9 @@ TEST(DcSctpSocketTest, ResendCookieEchoAndEstablishConnection) { a.socket.ReceivePacket(z.cb.ConsumeSentPacket()); // COOKIE_ECHO is never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(init_packet.descriptors()[0].type, CookieEchoChunk::kType); AdvanceTime(a, z, a.options.t1_init_timeout); @@ -714,16 +719,18 @@ TEST(DcSctpSocketTest, ResendingCookieEchoTooManyTimesAborts) { a.socket.ReceivePacket(z.cb.ConsumeSentPacket()); // COOKIE_ECHO is never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(init_packet.descriptors()[0].type, CookieEchoChunk::kType); for (int i = 0; i < *a.options.max_init_retransmits; ++i) { AdvanceTime(a, z, a.options.t1_cookie_timeout * (1 << i)); // COOKIE_ECHO is resent - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket resent_init_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket resent_init_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(resent_init_packet.descriptors()[0].type, CookieEchoChunk::kType); } @@ -751,8 +758,9 @@ TEST(DcSctpSocketTest, DoesntSendMorePacketsUntilCookieAckHasBeenReceived) { a.socket.ReceivePacket(z.cb.ConsumeSentPacket()); // COOKIE_ECHO is never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket cookie_echo_packet1, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket cookie_echo_packet1, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_THAT(cookie_echo_packet1.descriptors(), SizeIs(2)); EXPECT_EQ(cookie_echo_packet1.descriptors()[0].type, CookieEchoChunk::kType); EXPECT_EQ(cookie_echo_packet1.descriptors()[1].type, DataChunk::kType); @@ -771,8 +779,9 @@ TEST(DcSctpSocketTest, DoesntSendMorePacketsUntilCookieAckHasBeenReceived) { AdvanceTime(a, z, a.options.t1_cookie_timeout - a.options.rto_initial); // And this COOKIE-ECHO and DATA is also lost - never received by Z. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket cookie_echo_packet2, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket cookie_echo_packet2, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_THAT(cookie_echo_packet2.descriptors(), SizeIs(2)); EXPECT_EQ(cookie_echo_packet2.descriptors()[0].type, CookieEchoChunk::kType); EXPECT_EQ(cookie_echo_packet2.descriptors()[1].type, DataChunk::kType); @@ -836,8 +845,9 @@ TEST(DcSctpSocketTest, ShutdownTimerExpiresTooManyTimeClosesConnection) { AdvanceTime(a, z, DurationMs(a.options.rto_initial * (1 << i))); // Dropping every shutdown chunk. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(packet.descriptors()[0].type, ShutdownChunk::kType); EXPECT_TRUE(a.cb.ConsumeSentPacket().empty()); } @@ -847,8 +857,9 @@ TEST(DcSctpSocketTest, ShutdownTimerExpiresTooManyTimeClosesConnection) { a.options.rto_initial * (1 << *a.options.max_retransmissions)); EXPECT_EQ(a.socket.state(), SocketState::kClosed); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z.options)); EXPECT_EQ(packet.descriptors()[0].type, AbortChunk::kType); EXPECT_TRUE(a.cb.ConsumeSentPacket().empty()); } @@ -956,8 +967,9 @@ TEST_P(DcSctpSocketParametrizedTest, SendingHeartbeatAnswersWithAck) { a.socket.ReceivePacket(b.Build()); // HEARTBEAT_ACK is sent as a reply. Capture it. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket ack_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket ack_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z->options)); ASSERT_THAT(ack_packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( HeartbeatAckChunk ack, @@ -981,7 +993,7 @@ TEST_P(DcSctpSocketParametrizedTest, ExpectHeartbeatToBeSent) { std::vector hb_packet_raw = a.cb.ConsumeSentPacket(); ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket hb_packet, - SctpPacket::Parse(hb_packet_raw)); + SctpPacket::Parse(hb_packet_raw, z->options)); ASSERT_THAT(hb_packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( HeartbeatRequestChunk hb, @@ -1018,8 +1030,9 @@ TEST_P(DcSctpSocketParametrizedTest, AdvanceTime(a, *z, time_to_next_hearbeat); // Dropping every heartbeat. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket hb_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket hb_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z->options)); EXPECT_EQ(hb_packet.descriptors()[0].type, HeartbeatRequestChunk::kType); RTC_LOG(LS_INFO) << "Letting the heartbeat expire."; @@ -1072,7 +1085,7 @@ TEST_P(DcSctpSocketParametrizedTest, RecoversAfterASuccessfulAck) { std::vector hb_packet_raw = a.cb.ConsumeSentPacket(); ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket hb_packet, - SctpPacket::Parse(hb_packet_raw)); + SctpPacket::Parse(hb_packet_raw, z->options)); ASSERT_THAT(hb_packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( HeartbeatRequestChunk hb, @@ -1092,8 +1105,9 @@ TEST_P(DcSctpSocketParametrizedTest, RecoversAfterASuccessfulAck) { RTC_LOG(LS_INFO) << "Expecting a new heartbeat"; AdvanceTime(a, *z, time_to_next_hearbeat); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket another_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket another_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z->options)); EXPECT_EQ(another_packet.descriptors()[0].type, HeartbeatRequestChunk::kType); } @@ -1469,8 +1483,9 @@ TEST_P(DcSctpSocketParametrizedTest, ReceivingUnknownChunkRespondsWithError) { a.socket.ReceivePacket(b.Build()); // ERROR is sent as a reply. Capture it. - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket reply_packet, - SctpPacket::Parse(a.cb.ConsumeSentPacket())); + ASSERT_HAS_VALUE_AND_ASSIGN( + SctpPacket reply_packet, + SctpPacket::Parse(a.cb.ConsumeSentPacket(), z->options)); ASSERT_THAT(reply_packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( ErrorChunk error, ErrorChunk::Parse(reply_packet.descriptors()[0].data)); @@ -1517,7 +1532,7 @@ TEST(DcSctpSocketTest, PassingHighWatermarkWillOnlyAcceptCumAckTsn) { a.socket.Connect(); std::vector init_data = a.cb.ConsumeSentPacket(); ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(init_data)); + SctpPacket::Parse(init_data, z.options)); ASSERT_HAS_VALUE_AND_ASSIGN( InitChunk init_chunk, InitChunk::Parse(init_packet.descriptors()[0].data)); @@ -2237,7 +2252,7 @@ TEST(DcSctpSocketTest, ReceiveBothUnorderedAndOrderedWithSameTSN) { a.socket.Connect(); std::vector init_data = a.cb.ConsumeSentPacket(); ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket init_packet, - SctpPacket::Parse(init_data)); + SctpPacket::Parse(init_data, z.options)); ASSERT_HAS_VALUE_AND_ASSIGN( InitChunk init_chunk, InitChunk::Parse(init_packet.descriptors()[0].data)); diff --git a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc index faa0e3da06ea4..d5731924402ea 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc @@ -37,6 +37,7 @@ DcSctpOptions MakeOptions(DurationMs heartbeat_interval) { DcSctpOptions options; options.heartbeat_interval_include_rtt = false; options.heartbeat_interval = heartbeat_interval; + options.enable_zero_checksum = false; return options; } @@ -83,7 +84,8 @@ TEST_F(HeartbeatHandlerTest, HasRunningHeartbeatIntervalTimer) { // Validate that a heartbeat request was sent. std::vector payload = callbacks_.ConsumeSentPacket(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(payload, options_)); ASSERT_THAT(packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( @@ -101,7 +103,8 @@ TEST_F(HeartbeatHandlerTest, RepliesToHeartbeatRequests) { handler_.HandleHeartbeatRequest(std::move(request)); std::vector payload = callbacks_.ConsumeSentPacket(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(payload, options_)); ASSERT_THAT(packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( @@ -120,7 +123,8 @@ TEST_F(HeartbeatHandlerTest, SendsHeartbeatRequestsOnIdleChannel) { // Grab the request, and make a response. std::vector payload = callbacks_.ConsumeSentPacket(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(payload, options_)); ASSERT_THAT(packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( @@ -143,7 +147,8 @@ TEST_F(HeartbeatHandlerTest, DoesntObserveInvalidHeartbeats) { // Grab the request, and make a response. std::vector payload = callbacks_.ConsumeSentPacket(); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(payload, options_)); ASSERT_THAT(packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( diff --git a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc index d3fa98752cdb6..503cc89094421 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc @@ -149,7 +149,7 @@ class StreamResetHandlerTest : public testing::Test { } std::vector responses; - absl::optional p = SctpPacket::Parse(payload); + absl::optional p = SctpPacket::Parse(payload, DcSctpOptions()); if (!p.has_value()) { EXPECT_TRUE(false); return {}; @@ -504,7 +504,8 @@ TEST_F(StreamResetHandlerTest, SendOutgoingResetRetransmitOnInProgress) { std::vector payload = callbacks_.ConsumeSentPacket(); ASSERT_FALSE(payload.empty()); - ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload)); + ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, + SctpPacket::Parse(payload, DcSctpOptions())); ASSERT_THAT(packet.descriptors(), SizeIs(1)); ASSERT_HAS_VALUE_AND_ASSIGN( ReConfigChunk reconfig2, diff --git a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block_test.cc b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block_test.cc new file mode 100644 index 0000000000000..40aea58d4bf8e --- /dev/null +++ b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block_test.cc @@ -0,0 +1,119 @@ +/* + * Copyright (c) 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 "net/dcsctp/socket/transmission_control_block.h" + +#include +#include +#include +#include +#include + +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "api/task_queue/task_queue_base.h" +#include "net/dcsctp/common/handover_testing.h" +#include "net/dcsctp/common/internal_types.h" +#include "net/dcsctp/packet/chunk/reconfig_chunk.h" +#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h" +#include "net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h" +#include "net/dcsctp/packet/parameter/parameter.h" +#include "net/dcsctp/packet/parameter/reconfiguration_response_parameter.h" +#include "net/dcsctp/public/dcsctp_message.h" +#include "net/dcsctp/rx/data_tracker.h" +#include "net/dcsctp/rx/reassembly_queue.h" +#include "net/dcsctp/socket/capabilities.h" +#include "net/dcsctp/socket/mock_context.h" +#include "net/dcsctp/socket/mock_dcsctp_socket_callbacks.h" +#include "net/dcsctp/testing/data_generator.h" +#include "net/dcsctp/testing/testing_macros.h" +#include "net/dcsctp/timer/timer.h" +#include "net/dcsctp/tx/mock_send_queue.h" +#include "net/dcsctp/tx/retransmission_queue.h" +#include "rtc_base/gunit.h" +#include "test/gmock.h" + +namespace dcsctp { +namespace { +using ::testing::Return; +using ::testing::StrictMock; + +constexpr VerificationTag kMyVerificationTag = VerificationTag(123); +constexpr VerificationTag kPeerVerificationTag = VerificationTag(456); +constexpr TSN kMyInitialTsn = TSN(10); +constexpr TSN kPeerInitialTsn = TSN(1000); +constexpr size_t kArwnd = 65536; +constexpr TieTag kTieTag = TieTag(12345678); + +class TransmissionControlBlockTest : public testing::Test { + protected: + TransmissionControlBlockTest() + : sender_(callbacks_, on_send_fn_.AsStdFunction()), + timer_manager_([this](webrtc::TaskQueueBase::DelayPrecision precision) { + return callbacks_.CreateTimeout(precision); + }) {} + + DcSctpOptions options_; + Capabilities capabilities_; + StrictMock callbacks_; + StrictMock send_queue_; + testing::MockFunction, SendPacketStatus)> + on_send_fn_; + testing::MockFunction on_connection_established; + PacketSender sender_; + TimerManager timer_manager_; +}; + +TEST_F(TransmissionControlBlockTest, LogsBasicInfoInToString) { + EXPECT_CALL(send_queue_, EnableMessageInterleaving); + + capabilities_.negotiated_maximum_incoming_streams = 1000; + capabilities_.negotiated_maximum_outgoing_streams = 2000; + TransmissionControlBlock tcb( + timer_manager_, "log: ", options_, capabilities_, callbacks_, send_queue_, + kMyVerificationTag, kMyInitialTsn, kPeerVerificationTag, kPeerInitialTsn, + kArwnd, kTieTag, sender_, on_connection_established.AsStdFunction()); + + EXPECT_EQ(tcb.ToString(), + "verification_tag=000001c8, last_cumulative_ack=999, capabilities= " + "max_in=1000 max_out=2000"); +} + +TEST_F(TransmissionControlBlockTest, LogsAllCapabilitiesInToSring) { + EXPECT_CALL(send_queue_, EnableMessageInterleaving); + + capabilities_.negotiated_maximum_incoming_streams = 1000; + capabilities_.negotiated_maximum_outgoing_streams = 2000; + capabilities_.message_interleaving = true; + capabilities_.partial_reliability = true; + capabilities_.reconfig = true; + + TransmissionControlBlock tcb( + timer_manager_, "log: ", options_, capabilities_, callbacks_, send_queue_, + kMyVerificationTag, kMyInitialTsn, kPeerVerificationTag, kPeerInitialTsn, + kArwnd, kTieTag, sender_, on_connection_established.AsStdFunction()); + + EXPECT_EQ(tcb.ToString(), + "verification_tag=000001c8, last_cumulative_ack=999, " + "capabilities=PR,IL,Reconfig, max_in=1000 max_out=2000"); +} + +TEST_F(TransmissionControlBlockTest, IsInitiallyHandoverReady) { + EXPECT_CALL(send_queue_, EnableMessageInterleaving); + EXPECT_CALL(send_queue_, HasStreamsReadyToBeReset).WillOnce(Return(false)); + + TransmissionControlBlock tcb( + timer_manager_, "log: ", options_, capabilities_, callbacks_, send_queue_, + kMyVerificationTag, kMyInitialTsn, kPeerVerificationTag, kPeerInitialTsn, + kArwnd, kTieTag, sender_, on_connection_established.AsStdFunction()); + + EXPECT_TRUE(tcb.GetHandoverReadiness().IsReady()); +} +} // namespace +} // namespace dcsctp diff --git a/third_party/libwebrtc/p2p/base/ice_transport_internal.h b/third_party/libwebrtc/p2p/base/ice_transport_internal.h index 3a93ab04844a7..55f12382aabd6 100644 --- a/third_party/libwebrtc/p2p/base/ice_transport_internal.h +++ b/third_party/libwebrtc/p2p/base/ice_transport_internal.h @@ -228,12 +228,6 @@ enum class IceTransportState { STATE_FAILED }; -// TODO(zhihuang): Remove this once it's no longer used in -// remoting/protocol/libjingle_transport_factory.cc -enum IceProtocolType { - ICEPROTO_RFC5245 // Standard RFC 5245 version of ICE. -}; - // IceTransportInternal is an internal abstract class that does ICE. // Once the public interface is supported, // (https://www.w3.org/TR/webrtc/#rtcicetransport) @@ -256,10 +250,6 @@ class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal { virtual void SetIceTiebreaker(uint64_t tiebreaker) = 0; - // TODO(zhihuang): Remove this once it's no longer called in - // remoting/protocol/libjingle_transport_factory.cc - virtual void SetIceProtocolType(IceProtocolType type) {} - virtual void SetIceCredentials(absl::string_view ice_ufrag, absl::string_view ice_pwd); diff --git a/third_party/libwebrtc/p2p/base/p2p_transport_channel_unittest.cc b/third_party/libwebrtc/p2p/base/p2p_transport_channel_unittest.cc index 87e5706bb2db9..02cc483d312a2 100644 --- a/third_party/libwebrtc/p2p/base/p2p_transport_channel_unittest.cc +++ b/third_party/libwebrtc/p2p/base/p2p_transport_channel_unittest.cc @@ -412,7 +412,8 @@ class P2PTransportChannelTestBase : public ::testing::Test, rtc::FakeNetworkManager network_manager_; std::unique_ptr allocator_; - webrtc::AsyncDnsResolverFactoryInterface* async_dns_resolver_factory_; + webrtc::AsyncDnsResolverFactoryInterface* async_dns_resolver_factory_ = + nullptr; ChannelData cd1_; ChannelData cd2_; IceRole role_; diff --git a/third_party/libwebrtc/p2p/base/port_unittest.cc b/third_party/libwebrtc/p2p/base/port_unittest.cc index 3a0021699cfb9..81096e6607f16 100644 --- a/third_party/libwebrtc/p2p/base/port_unittest.cc +++ b/third_party/libwebrtc/p2p/base/port_unittest.cc @@ -517,12 +517,10 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> { return &networks_.back(); } - rtc::Network* MakeNetworkMultipleAddrs( - const SocketAddress& global_addr, - const SocketAddress& link_local_addr, - const webrtc::FieldTrialsView* field_trials) { + rtc::Network* MakeNetworkMultipleAddrs(const SocketAddress& global_addr, + const SocketAddress& link_local_addr) { networks_.emplace_back("unittest", "unittest", global_addr.ipaddr(), 32, - rtc::ADAPTER_TYPE_UNKNOWN, field_trials); + rtc::ADAPTER_TYPE_UNKNOWN); networks_.back().AddIP(link_local_addr.ipaddr()); networks_.back().AddIP(global_addr.ipaddr()); networks_.back().AddIP(link_local_addr.ipaddr()); @@ -545,12 +543,11 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr CreateUdpPortMultipleAddrs( const SocketAddress& global_addr, const SocketAddress& link_local_addr, - PacketSocketFactory* socket_factory, - const webrtc::test::ScopedKeyValueConfig& field_trials) { + PacketSocketFactory* socket_factory) { auto port = UDPPort::Create( &main_, socket_factory, - MakeNetworkMultipleAddrs(global_addr, link_local_addr, &field_trials), - 0, 0, username_, password_, true, absl::nullopt, &field_trials); + MakeNetworkMultipleAddrs(global_addr, link_local_addr), 0, 0, username_, + password_, true, absl::nullopt, &field_trials_); port->SetIceTiebreaker(kTiebreakerDefault); return port; } @@ -1770,9 +1767,6 @@ TEST_F(PortTest, TestUdpSingleAddressV6CrossTypePorts) { } TEST_F(PortTest, TestUdpMultipleAddressesV6CrossTypePorts) { - webrtc::test::ScopedKeyValueConfig field_trials( - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,PreferGlobalIPv6Address:true/"); FakePacketSocketFactory factory; std::unique_ptr ports[5]; SocketAddress addresses[5] = { @@ -1782,8 +1776,8 @@ TEST_F(PortTest, TestUdpMultipleAddressesV6CrossTypePorts) { for (int i = 0; i < 5; i++) { FakeAsyncPacketSocket* socket = new FakeAsyncPacketSocket(); factory.set_next_udp_socket(socket); - ports[i] = CreateUdpPortMultipleAddrs(addresses[i], kLinkLocalIPv6Addr, - &factory, field_trials); + ports[i] = + CreateUdpPortMultipleAddrs(addresses[i], kLinkLocalIPv6Addr, &factory); ports[i]->SetIceTiebreaker(kTiebreakerDefault); socket->set_state(AsyncPacketSocket::STATE_BINDING); socket->SignalAddressReady(socket, addresses[i]); diff --git a/third_party/libwebrtc/p2p/base/pseudo_tcp_unittest.cc b/third_party/libwebrtc/p2p/base/pseudo_tcp_unittest.cc index e56c6fa2c55e9..48df2b119ace7 100644 --- a/third_party/libwebrtc/p2p/base/pseudo_tcp_unittest.cc +++ b/third_party/libwebrtc/p2p/base/pseudo_tcp_unittest.cc @@ -294,19 +294,19 @@ class PseudoTcpTest : public PseudoTcpTestBase { void ReadData() { char block[kBlockSize]; size_t position; - int rcvd; + int received; do { - rcvd = remote_.Recv(block, sizeof(block)); - if (rcvd != -1) { + received = remote_.Recv(block, sizeof(block)); + if (received != -1) { size_t written; int error; recv_stream_.Write( - rtc::MakeArrayView(reinterpret_cast(block), rcvd), + rtc::MakeArrayView(reinterpret_cast(block), received), written, error); recv_stream_.GetPosition(&position); RTC_LOG(LS_VERBOSE) << "Received: " << position; } - } while (rcvd > 0); + } while (received > 0); } void WriteData(bool* done) { size_t position, tosend; @@ -417,19 +417,20 @@ class PseudoTcpTestPingPong : public PseudoTcpTestBase { void ReadData() { char block[kBlockSize]; size_t position; - int rcvd; + int received; do { - rcvd = receiver_->Recv(block, sizeof(block)); - if (rcvd != -1) { + received = receiver_->Recv(block, sizeof(block)); + if (received != -1) { size_t written; int error; recv_stream_.Write( - rtc::MakeArrayView(reinterpret_cast(block), rcvd), + rtc::MakeArrayView(reinterpret_cast(block), + received), written, error); recv_stream_.GetPosition(&position); RTC_LOG(LS_VERBOSE) << "Received: " << position; } - } while (rcvd > 0); + } while (received > 0); } void WriteData() { size_t position, tosend; @@ -524,20 +525,20 @@ class PseudoTcpTestReceiveWindow : public PseudoTcpTestBase { void ReadUntilIOPending() { char block[kBlockSize]; size_t position; - int rcvd; + int received; do { - rcvd = remote_.Recv(block, sizeof(block)); - if (rcvd != -1) { + received = remote_.Recv(block, sizeof(block)); + if (received != -1) { size_t written; int error; recv_stream_.Write( - rtc::MakeArrayView(reinterpret_cast(block), rcvd), + rtc::MakeArrayView(reinterpret_cast(block), received), written, error); recv_stream_.GetPosition(&position); RTC_LOG(LS_VERBOSE) << "Received: " << position; } - } while (rcvd > 0); + } while (received > 0); recv_stream_.GetPosition(&position); recv_position_.push_back(position); diff --git a/third_party/libwebrtc/p2p/base/stun_port.cc b/third_party/libwebrtc/p2p/base/stun_port.cc index 9fd39da8f3129..82832d80626e2 100644 --- a/third_party/libwebrtc/p2p/base/stun_port.cc +++ b/third_party/libwebrtc/p2p/base/stun_port.cc @@ -29,26 +29,6 @@ namespace cricket { -namespace { - -bool ResolveStunHostnameForFamily(const webrtc::FieldTrialsView& field_trials) { - // Bug fix for STUN hostname resolution on IPv6. - // Field trial key reserved in bugs.webrtc.org/14334 - static constexpr char field_trial_name[] = - "WebRTC-IPv6NetworkResolutionFixes"; - if (!field_trials.IsEnabled(field_trial_name)) { - return false; - } - - webrtc::FieldTrialParameter resolve_stun_hostname_for_family( - "ResolveStunHostnameForFamily", /*default_value=*/false); - webrtc::ParseFieldTrial({&resolve_stun_hostname_for_family}, - field_trials.Lookup(field_trial_name)); - return resolve_stun_hostname_for_family; -} - -} // namespace - // TODO(?): Move these to a common place (used in relayport too) const int RETRY_TIMEOUT = 50 * 1000; // 50 seconds @@ -163,11 +143,7 @@ void UDPPort::AddressResolver::Resolve( done_(it->first, it->second->result().GetError()); } }; - if (ResolveStunHostnameForFamily(field_trials)) { - resolver_ptr->Start(address, family, std::move(callback)); - } else { - resolver_ptr->Start(address, std::move(callback)); - } + resolver_ptr->Start(address, family, std::move(callback)); } bool UDPPort::AddressResolver::GetResolvedAddress( diff --git a/third_party/libwebrtc/p2p/base/stun_port_unittest.cc b/third_party/libwebrtc/p2p/base/stun_port_unittest.cc index 3d56636a9b282..def4951063b20 100644 --- a/third_party/libwebrtc/p2p/base/stun_port_unittest.cc +++ b/third_party/libwebrtc/p2p/base/stun_port_unittest.cc @@ -317,8 +317,8 @@ TEST_F(StunPortWithMockDnsResolverTest, TestPrepareAddressHostname) { SetDnsResolverExpectations( [](webrtc::MockAsyncDnsResolver* resolver, webrtc::MockAsyncDnsResolverResult* resolver_result) { - EXPECT_CALL(*resolver, Start(kValidHostnameAddr, _)) - .WillOnce(InvokeArgument<1>()); + EXPECT_CALL(*resolver, Start(kValidHostnameAddr, /*family=*/AF_INET, _)) + .WillOnce(InvokeArgument<2>()); EXPECT_CALL(*resolver, result) .WillRepeatedly(ReturnPointee(resolver_result)); EXPECT_CALL(*resolver_result, GetError).WillOnce(Return(0)); @@ -666,84 +666,6 @@ TEST_F(StunIPv6PortTestWithMockDnsResolver, TestPrepareAddressHostname) { SetDnsResolverExpectations( [](webrtc::MockAsyncDnsResolver* resolver, webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start without family arg. - EXPECT_CALL(*resolver, Start(kValidHostnameAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillOnce(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("::1", 5000)), - Return(true))); - }); - CreateStunPort(kValidHostnameAddr); - PrepareAddress(); - EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); - ASSERT_EQ(1U, port()->Candidates().size()); - EXPECT_TRUE(kIPv6LocalAddr.EqualIPs(port()->Candidates()[0].address())); - EXPECT_EQ(kIPv6StunCandidatePriority, port()->Candidates()[0].priority()); -} - -TEST_F(StunIPv6PortTestWithMockDnsResolver, - TestPrepareAddressHostnameFamilyFieldTrialDisabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - "WebRTC-IPv6NetworkResolutionFixes/Disabled/"); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start without family arg. - EXPECT_CALL(*resolver, Start(kValidHostnameAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillOnce(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("::1", 5000)), - Return(true))); - }); - CreateStunPort(kValidHostnameAddr, &field_trials); - PrepareAddress(); - EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); - ASSERT_EQ(1U, port()->Candidates().size()); - EXPECT_TRUE(kIPv6LocalAddr.EqualIPs(port()->Candidates()[0].address())); - EXPECT_EQ(kIPv6StunCandidatePriority, port()->Candidates()[0].priority()); -} - -TEST_F(StunIPv6PortTestWithMockDnsResolver, - TestPrepareAddressHostnameFamilyFieldTrialParamDisabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,ResolveStunHostnameForFamily:false/"); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start without family arg. - EXPECT_CALL(*resolver, Start(kValidHostnameAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillOnce(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("::1", 5000)), - Return(true))); - }); - CreateStunPort(kValidHostnameAddr, &field_trials); - PrepareAddress(); - EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); - ASSERT_EQ(1U, port()->Candidates().size()); - EXPECT_TRUE(kIPv6LocalAddr.EqualIPs(port()->Candidates()[0].address())); - EXPECT_EQ(kIPv6StunCandidatePriority, port()->Candidates()[0].priority()); -} - -TEST_F(StunIPv6PortTestWithMockDnsResolver, - TestPrepareAddressHostnameFamilyFieldTrialEnabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,ResolveStunHostnameForFamily:true/"); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start _with_ family arg. EXPECT_CALL(*resolver, Start(kValidHostnameAddr, /*family=*/AF_INET6, _)) .WillOnce(InvokeArgument<2>()); @@ -754,7 +676,7 @@ TEST_F(StunIPv6PortTestWithMockDnsResolver, .WillOnce(DoAll(SetArgPointee<1>(SocketAddress("::1", 5000)), Return(true))); }); - CreateStunPort(kValidHostnameAddr, &field_trials); + CreateStunPort(kValidHostnameAddr); PrepareAddress(); EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); ASSERT_EQ(1U, port()->Candidates().size()); diff --git a/third_party/libwebrtc/p2p/base/turn_port.cc b/third_party/libwebrtc/p2p/base/turn_port.cc index 089910e07229d..073fd7e4cf42a 100644 --- a/third_party/libwebrtc/p2p/base/turn_port.cc +++ b/third_party/libwebrtc/p2p/base/turn_port.cc @@ -34,26 +34,6 @@ namespace cricket { -namespace { - -bool ResolveTurnHostnameForFamily(const webrtc::FieldTrialsView& field_trials) { - // Bug fix for TURN hostname resolution on IPv6. - // Field trial key reserved in bugs.webrtc.org/14334 - static constexpr char field_trial_name[] = - "WebRTC-IPv6NetworkResolutionFixes"; - if (!field_trials.IsEnabled(field_trial_name)) { - return false; - } - - webrtc::FieldTrialParameter resolve_turn_hostname_for_family( - "ResolveTurnHostnameForFamily", /*default_value=*/false); - webrtc::ParseFieldTrial({&resolve_turn_hostname_for_family}, - field_trials.Lookup(field_trial_name)); - return resolve_turn_hostname_for_family; -} - -} // namespace - using ::webrtc::SafeTask; using ::webrtc::TaskQueueBase; using ::webrtc::TimeDelta; @@ -861,12 +841,7 @@ void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) { server_address_.address = resolved_address; PrepareAddress(); }; - // TODO(bugs.webrtc.org/14733): remove duplicate resolution with STUN port. - if (ResolveTurnHostnameForFamily(field_trials())) { - resolver_->Start(address, Network()->family(), std::move(callback)); - } else { - resolver_->Start(address, std::move(callback)); - } + resolver_->Start(address, Network()->family(), std::move(callback)); } void TurnPort::OnSendStunPacket(const void* data, diff --git a/third_party/libwebrtc/p2p/base/turn_port_unittest.cc b/third_party/libwebrtc/p2p/base/turn_port_unittest.cc index d63dd4a75c9a5..c77a8c04f260a 100644 --- a/third_party/libwebrtc/p2p/base/turn_port_unittest.cc +++ b/third_party/libwebrtc/p2p/base/turn_port_unittest.cc @@ -1912,8 +1912,8 @@ TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolved) { SetDnsResolverExpectations( [](webrtc::MockAsyncDnsResolver* resolver, webrtc::MockAsyncDnsResolverResult* resolver_result) { - EXPECT_CALL(*resolver, Start(kTurnValidAddr, _)) - .WillOnce(InvokeArgument<1>()); + EXPECT_CALL(*resolver, Start(kTurnValidAddr, /*family=*/AF_INET, _)) + .WillOnce(InvokeArgument<2>()); EXPECT_CALL(*resolver, result) .WillRepeatedly(ReturnPointee(resolver_result)); EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0)); @@ -1932,85 +1932,6 @@ TEST_F(TurnPortWithMockDnsResolverTest, TestHostnameResolvedIPv6Network) { SetDnsResolverExpectations( [](webrtc::MockAsyncDnsResolver* resolver, webrtc::MockAsyncDnsResolverResult* resolver_result) { - EXPECT_CALL(*resolver, Start(kTurnValidAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce( - DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true))); - }); - TestTurnAllocateSucceeds(kSimulatedRtt * 2); -} - -// Test an allocation from a TURN server specified by a hostname on an IPv6 -// network, without network family-specific resolution. -TEST_F(TurnPortWithMockDnsResolverTest, - TestHostnameResolvedIPv6NetworkFamilyFieldTrialDisabled) { - webrtc::test::ScopedKeyValueConfig override_field_trials( - field_trials_, "WebRTC-IPv6NetworkResolutionFixes/Disabled/"); - turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP); - CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword, - kTurnPortValidHostnameProtoAddr); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start without family arg. - EXPECT_CALL(*resolver, Start(kTurnValidAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce( - DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true))); - }); - TestTurnAllocateSucceeds(kSimulatedRtt * 2); -} - -// Test an allocation from a TURN server specified by a hostname on an IPv6 -// network, without network family-specific resolution. -TEST_F(TurnPortWithMockDnsResolverTest, - TestHostnameResolvedIPv6NetworkFamilyFieldTrialParamDisabled) { - webrtc::test::ScopedKeyValueConfig override_field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,ResolveTurnHostnameForFamily:false/"); - turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP); - CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword, - kTurnPortValidHostnameProtoAddr); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start without family arg. - EXPECT_CALL(*resolver, Start(kTurnValidAddr, _)) - .WillOnce(InvokeArgument<1>()); - EXPECT_CALL(*resolver, result) - .WillRepeatedly(ReturnPointee(resolver_result)); - EXPECT_CALL(*resolver_result, GetError).WillRepeatedly(Return(0)); - EXPECT_CALL(*resolver_result, GetResolvedAddress(AF_INET6, _)) - .WillOnce( - DoAll(SetArgPointee<1>(kTurnUdpIPv6IntAddr), Return(true))); - }); - TestTurnAllocateSucceeds(kSimulatedRtt * 2); -} - -// Test an allocation from a TURN server specified by a hostname on an IPv6 -// network, with network family-specific resolution. -TEST_F(TurnPortWithMockDnsResolverTest, - TestHostnameResolvedIPv6NetworkFieldTrialEnabled) { - webrtc::test::ScopedKeyValueConfig override_field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,ResolveTurnHostnameForFamily:true/"); - turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, PROTO_UDP); - CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword, - kTurnPortValidHostnameProtoAddr); - SetDnsResolverExpectations( - [](webrtc::MockAsyncDnsResolver* resolver, - webrtc::MockAsyncDnsResolverResult* resolver_result) { - // Expect to call Resolver::Start _with_ family arg. EXPECT_CALL(*resolver, Start(kTurnValidAddr, /*family=*/AF_INET6, _)) .WillOnce(InvokeArgument<2>()); EXPECT_CALL(*resolver, result) diff --git a/third_party/libwebrtc/p2p/client/basic_port_allocator.cc b/third_party/libwebrtc/p2p/client/basic_port_allocator.cc index e36f266f15c7c..ac1901bc172db 100644 --- a/third_party/libwebrtc/p2p/client/basic_port_allocator.cc +++ b/third_party/libwebrtc/p2p/client/basic_port_allocator.cc @@ -154,21 +154,6 @@ std::string NetworksToString(const std::vector& networks) { return ost.Release(); } -bool IsDiversifyIpv6InterfacesEnabled( - const webrtc::FieldTrialsView* field_trials) { - // webrtc:14334: Improve IPv6 network resolution and candidate creation - if (field_trials && - field_trials->IsEnabled("WebRTC-IPv6NetworkResolutionFixes")) { - webrtc::FieldTrialParameter diversify_ipv6_interfaces( - "DiversifyIpv6Interfaces", false); - webrtc::ParseFieldTrial( - {&diversify_ipv6_interfaces}, - field_trials->Lookup("WebRTC-IPv6NetworkResolutionFixes")); - return diversify_ipv6_interfaces; - } - return false; -} - } // namespace const uint32_t DISABLE_ALL_PHASES = @@ -768,6 +753,10 @@ std::vector BasicPortAllocatorSession::GetNetworks() { networks.insert(networks.end(), any_address_networks.begin(), any_address_networks.end()); } + RTC_LOG(LS_INFO) << "Count of networks: " << networks.size(); + for (const rtc::Network* network : networks) { + RTC_LOG(LS_INFO) << network->ToString(); + } } // Filter out link-local networks if needed. if (flags() & PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS) { @@ -809,41 +798,20 @@ std::vector BasicPortAllocatorSession::GetNetworks() { } // Lastly, if we have a limit for the number of IPv6 network interfaces (by - // default, it's 5), remove networks to ensure that limit is satisfied. - // - // TODO(deadbeef): Instead of just taking the first N arbitrary IPv6 - // networks, we could try to choose a set that's "most likely to work". It's - // hard to define what that means though; it's not just "lowest cost". - // Alternatively, we could just focus on making our ICE pinging logic smarter - // such that this filtering isn't necessary in the first place. - const webrtc::FieldTrialsView* field_trials = allocator_->field_trials(); - if (IsDiversifyIpv6InterfacesEnabled(field_trials)) { - std::vector ipv6_networks; - for (auto it = networks.begin(); it != networks.end();) { - if ((*it)->prefix().family() == AF_INET6) { - ipv6_networks.push_back(*it); - it = networks.erase(it); - continue; - } - ++it; - } - ipv6_networks = - SelectIPv6Networks(ipv6_networks, allocator_->max_ipv6_networks()); - networks.insert(networks.end(), ipv6_networks.begin(), ipv6_networks.end()); - } else { - int ipv6_networks = 0; - for (auto it = networks.begin(); it != networks.end();) { - if ((*it)->prefix().family() == AF_INET6) { - if (ipv6_networks >= allocator_->max_ipv6_networks()) { - it = networks.erase(it); - continue; - } else { - ++ipv6_networks; - } - } - ++it; + // default, it's 5), pick IPv6 networks from different interfaces in a + // priority order and stick to the limit. + std::vector ipv6_networks; + for (auto it = networks.begin(); it != networks.end();) { + if ((*it)->prefix().family() == AF_INET6) { + ipv6_networks.push_back(*it); + it = networks.erase(it); + continue; } + ++it; } + ipv6_networks = + SelectIPv6Networks(ipv6_networks, allocator_->max_ipv6_networks()); + networks.insert(networks.end(), ipv6_networks.begin(), ipv6_networks.end()); return networks; } diff --git a/third_party/libwebrtc/p2p/client/basic_port_allocator_unittest.cc b/third_party/libwebrtc/p2p/client/basic_port_allocator_unittest.cc index d1a91afd63e2a..710d32a98fbeb 100644 --- a/third_party/libwebrtc/p2p/client/basic_port_allocator_unittest.cc +++ b/third_party/libwebrtc/p2p/client/basic_port_allocator_unittest.cc @@ -2649,69 +2649,7 @@ TEST_F(BasicPortAllocatorTest, IPv6EtherAndWifiHaveHigherPriorityThanOthers) { EXPECT_TRUE(HasNetwork(networks, ethe1)); } -// Do not change the default IPv6 selection behavior if -// IPv6NetworkResolutionFixes is disabled. -TEST_F(BasicPortAllocatorTest, - NotDiversifyIPv6NetworkTypesIfIPv6NetworkResolutionFixesDisabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - field_trials_, "WebRTC-IPv6NetworkResolutionFixes/Disabled/"); - // Add three IPv6 network interfaces, but tell the allocator to only use two. - allocator().set_max_ipv6_networks(2); - AddInterface(kClientIPv6Addr, "ethe1", rtc::ADAPTER_TYPE_ETHERNET); - AddInterface(kClientIPv6Addr2, "ethe2", rtc::ADAPTER_TYPE_ETHERNET); - AddInterface(kClientIPv6Addr3, "wifi1", rtc::ADAPTER_TYPE_WIFI); - // To simplify the test, only gather UDP host candidates. - allocator().set_flags(PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_DISABLE_TCP | - PORTALLOCATOR_DISABLE_STUN | - PORTALLOCATOR_DISABLE_RELAY | - PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); - - ASSERT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); - session_->StartGettingPorts(); - EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, - kDefaultAllocationTimeout, fake_clock); - - EXPECT_EQ(2U, candidates_.size()); - // Wifi1 was not selected because it comes after ethe1 and ethe2. - EXPECT_FALSE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3)); -} - -// Do not change the default IPv6 selection behavior if -// IPv6NetworkResolutionFixes is enabled but DiversifyIpv6Interfaces is not -// enabled. -TEST_F(BasicPortAllocatorTest, - NotDiversifyIPv6NetworkTypesIfDiversifyIpv6InterfacesDisabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,DiversifyIpv6Interfaces:false/"); - // Add three IPv6 network interfaces, but tell the allocator to only use two. - allocator().set_max_ipv6_networks(2); - AddInterface(kClientIPv6Addr, "ethe1", rtc::ADAPTER_TYPE_ETHERNET); - AddInterface(kClientIPv6Addr2, "ethe2", rtc::ADAPTER_TYPE_ETHERNET); - AddInterface(kClientIPv6Addr3, "wifi1", rtc::ADAPTER_TYPE_WIFI); - // To simplify the test, only gather UDP host candidates. - allocator().set_flags(PORTALLOCATOR_ENABLE_IPV6 | PORTALLOCATOR_DISABLE_TCP | - PORTALLOCATOR_DISABLE_STUN | - PORTALLOCATOR_DISABLE_RELAY | - PORTALLOCATOR_ENABLE_IPV6_ON_WIFI); - - ASSERT_TRUE(CreateSession(cricket::ICE_CANDIDATE_COMPONENT_RTP)); - session_->StartGettingPorts(); - EXPECT_TRUE_SIMULATED_WAIT(candidate_allocation_done_, - kDefaultAllocationTimeout, fake_clock); - - EXPECT_EQ(2U, candidates_.size()); - // Wifi1 was not selected because it comes after ethe1 and ethe2. - EXPECT_FALSE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3)); -} - -TEST_F(BasicPortAllocatorTest, - Select2DifferentIntefacesIfDiversifyIpv6InterfacesEnabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,DiversifyIpv6Interfaces:true/"); +TEST_F(BasicPortAllocatorTest, Select2DifferentIntefaces) { allocator().set_max_ipv6_networks(2); AddInterface(kClientIPv6Addr, "ethe1", rtc::ADAPTER_TYPE_ETHERNET); AddInterface(kClientIPv6Addr2, "ethe2", rtc::ADAPTER_TYPE_ETHERNET); @@ -2736,12 +2674,7 @@ TEST_F(BasicPortAllocatorTest, EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr3)); } -TEST_F(BasicPortAllocatorTest, - Select3DifferentIntefacesIfDiversifyIpv6InterfacesEnabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,DiversifyIpv6Interfaces:true/"); +TEST_F(BasicPortAllocatorTest, Select3DifferentIntefaces) { allocator().set_max_ipv6_networks(3); AddInterface(kClientIPv6Addr, "ethe1", rtc::ADAPTER_TYPE_ETHERNET); AddInterface(kClientIPv6Addr2, "ethe2", rtc::ADAPTER_TYPE_ETHERNET); @@ -2767,12 +2700,7 @@ TEST_F(BasicPortAllocatorTest, EXPECT_TRUE(HasCandidate(candidates_, "local", "udp", kClientIPv6Addr5)); } -TEST_F(BasicPortAllocatorTest, - Select4DifferentIntefacesIfDiversifyIpv6InterfacesEnabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - field_trials_, - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,DiversifyIpv6Interfaces:true/"); +TEST_F(BasicPortAllocatorTest, Select4DifferentIntefaces) { allocator().set_max_ipv6_networks(4); AddInterface(kClientIPv6Addr, "ethe1", rtc::ADAPTER_TYPE_ETHERNET); AddInterface(kClientIPv6Addr2, "ethe2", rtc::ADAPTER_TYPE_ETHERNET); diff --git a/third_party/libwebrtc/pc/BUILD.gn b/third_party/libwebrtc/pc/BUILD.gn index 383e74668867c..48c8879145b6b 100644 --- a/third_party/libwebrtc/pc/BUILD.gn +++ b/third_party/libwebrtc/pc/BUILD.gn @@ -309,6 +309,7 @@ rtc_source_set("jsep_transport_controller") { ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/functional:any_invocable", "//third_party/abseil-cpp/absl/types:optional", ] } @@ -876,6 +877,7 @@ rtc_library("sctp_data_channel") { "../api:rtc_error", "../api:scoped_refptr", "../api:sequence_checker", + "../api/task_queue:pending_task_safety_flag", "../api/transport:datagram_transport_interface", "../media:media_channel", "../media:rtc_data_sctp_transport_internal", @@ -891,10 +893,7 @@ rtc_library("sctp_data_channel") { "../rtc_base/system:no_unique_address", "../rtc_base/system:unused", ] - absl_deps = [ - "//third_party/abseil-cpp/absl/cleanup", - "//third_party/abseil-cpp/absl/types:optional", - ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } rtc_library("data_channel_utils") { @@ -1325,7 +1324,6 @@ rtc_source_set("legacy_stats_collector") { "../api/video:video_rtp_headers", "../call:call_interfaces", "../media:media_channel", - "../media:media_channel_impl", "../media:rtc_media_base", "../modules/audio_processing:audio_processing_statistics", "../p2p:rtc_p2p", @@ -2214,9 +2212,17 @@ if (rtc_include_tests && !build_with_chromium) { "../api/audio_codecs:builtin_audio_encoder_factory", "../api/test/metrics:global_metrics_logger_and_exporter", "../api/test/metrics:metric", - "../api/video_codecs:builtin_video_decoder_factory", - "../api/video_codecs:builtin_video_encoder_factory", "../api/video_codecs:video_codecs_api", + "../api/video_codecs:video_decoder_factory_template", + "../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", @@ -2282,6 +2288,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:ssl", "../test:test_main", "../test:test_support", + "../test/time_controller:time_controller", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/types:optional", @@ -2304,6 +2311,7 @@ if (rtc_include_tests && !build_with_chromium) { "peer_connection_bundle_unittest.cc", "peer_connection_crypto_unittest.cc", "peer_connection_data_channel_unittest.cc", + "peer_connection_encodings_integrationtest.cc", "peer_connection_end_to_end_unittest.cc", "peer_connection_factory_unittest.cc", "peer_connection_field_trial_tests.cc", @@ -2461,6 +2469,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:net_helper", "../rtc_base:network", "../rtc_base:network_constants", + "../rtc_base:null_socket_server", "../rtc_base:refcount", "../rtc_base:rtc_base_tests_utils", "../rtc_base:rtc_certificate_generator", @@ -2477,6 +2486,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base/third_party/sigslot", "../system_wrappers:metrics", "../test:field_trial", + "../test:rtc_expect_death", "../test:run_loop", "../test:scoped_key_value_config", "../test/pc/sctp:fake_sctp_transport", @@ -2517,6 +2527,16 @@ if (rtc_include_tests && !build_with_chromium) { "../api/video_codecs:builtin_video_decoder_factory", "../api/video_codecs:builtin_video_encoder_factory", "../api/video_codecs:video_codecs_api", + "../api/video_codecs:video_decoder_factory_template", + "../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../call:call_interfaces", "../media:rtc_audio_video", "../media:rtc_media_base", @@ -2562,6 +2582,7 @@ if (rtc_include_tests && !build_with_chromium) { ":pc_test_utils", ":peer_connection_internal", ":sctp_data_channel", + "../rtc_base:null_socket_server", "../test:run_loop", "../test:test_support", ] @@ -2679,6 +2700,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:logging", "../rtc_base:macromagic", "../rtc_base:mdns_responder_interface", + "../rtc_base:null_socket_server", "../rtc_base:rtc_base_tests_utils", "../rtc_base:rtc_certificate_generator", "../rtc_base:rtc_event", @@ -2700,6 +2722,7 @@ if (rtc_include_tests && !build_with_chromium) { "../test:scoped_key_value_config", "../test:test_support", "../test/pc/sctp:fake_sctp_transport", + "../test/time_controller", ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", @@ -2733,6 +2756,8 @@ if (rtc_include_tests && !build_with_chromium) { "test/peer_connection_test_wrapper.cc", "test/peer_connection_test_wrapper.h", "test/rtc_stats_obtainer.h", + "test/simulcast_layer_util.cc", + "test/simulcast_layer_util.h", "test/test_sdp_strings.h", ] @@ -2746,6 +2771,8 @@ if (rtc_include_tests && !build_with_chromium) { ":rtp_receiver", ":rtp_sender", ":sctp_data_channel", + ":session_description", + ":simulcast_description", ":stream_collection", ":video_track_source", "../api:audio_options_api", @@ -2770,15 +2797,24 @@ if (rtc_include_tests && !build_with_chromium) { "../api/video:resolution", "../api/video:video_frame", "../api/video:video_rtp_headers", - "../api/video_codecs:builtin_video_decoder_factory", - "../api/video_codecs:builtin_video_encoder_factory", "../api/video_codecs:video_codecs_api", + "../api/video_codecs:video_decoder_factory_template", + "../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../api/video_codecs:video_encoder_factory_template", + "../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../call:call_interfaces", "../media:media_channel", "../media:media_channel_impl", "../media:rtc_media", "../media:rtc_media_base", "../media:rtc_media_tests_utils", + "../media:rtc_simulcast_encoder_adapter", "../modules/audio_device", "../modules/audio_processing", "../modules/audio_processing:api", @@ -2801,11 +2837,14 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base/synchronization:mutex", "../rtc_base/task_utils:repeating_task", "../rtc_base/third_party/sigslot", + "../test:frame_generator_capturer", "../test:scoped_key_value_config", "../test:test_support", - "../test:video_test_common", ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/types:optional", + ] } svc_tests_resources = [ diff --git a/third_party/libwebrtc/pc/data_channel_controller.cc b/third_party/libwebrtc/pc/data_channel_controller.cc index e1475e0dedf5f..1746170f64b43 100644 --- a/third_party/libwebrtc/pc/data_channel_controller.cc +++ b/third_party/libwebrtc/pc/data_channel_controller.cc @@ -21,11 +21,23 @@ namespace webrtc { -DataChannelController::~DataChannelController() {} +DataChannelController::~DataChannelController() { + RTC_DCHECK(sctp_data_channels_n_.empty()) + << "Missing call to TeardownDataChannelTransport_n?"; + RTC_DCHECK(!signaling_safety_.flag()->alive()) + << "Missing call to PrepareForShutdown?"; +} bool DataChannelController::HasDataChannels() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return !sctp_data_channels_.empty(); + auto has_channels = [&] { + RTC_DCHECK_RUN_ON(network_thread()); + return !sctp_data_channels_n_.empty(); + }; + + if (network_thread()->IsCurrent()) + return has_channels(); + + return network_thread()->BlockingCall(std::move(has_channels)); } bool DataChannelController::HasUsedDataChannels() const { @@ -37,45 +49,46 @@ RTCError DataChannelController::SendData( StreamId sid, const SendDataParams& params, const rtc::CopyOnWriteBuffer& payload) { - if (data_channel_transport()) - return DataChannelSendData(sid, params, payload); - RTC_LOG(LS_ERROR) << "SendData called before transport is ready"; - return RTCError(RTCErrorType::INVALID_STATE); + RTC_DCHECK_RUN_ON(network_thread()); + if (!data_channel_transport_) { + RTC_LOG(LS_ERROR) << "SendData called before transport is ready"; + return RTCError(RTCErrorType::INVALID_STATE); + } + return data_channel_transport_->SendData(sid.stream_id_int(), params, + payload); } void DataChannelController::AddSctpDataStream(StreamId sid) { - if (data_channel_transport()) { - network_thread()->BlockingCall([this, sid] { - if (data_channel_transport()) { - data_channel_transport()->OpenChannel(sid.stream_id_int()); - } - }); + RTC_DCHECK_RUN_ON(network_thread()); + RTC_DCHECK(sid.HasValue()); + if (data_channel_transport_) { + data_channel_transport_->OpenChannel(sid.stream_id_int()); } } void DataChannelController::RemoveSctpDataStream(StreamId sid) { - if (data_channel_transport()) { - network_thread()->BlockingCall([this, sid] { - if (data_channel_transport()) { - data_channel_transport()->CloseChannel(sid.stream_id_int()); - } - }); + RTC_DCHECK_RUN_ON(network_thread()); + if (data_channel_transport_) { + data_channel_transport_->CloseChannel(sid.stream_id_int()); } } -bool DataChannelController::ReadyToSendData() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return (data_channel_transport() && data_channel_transport_ready_to_send_); -} - void DataChannelController::OnChannelStateChanged( SctpDataChannel* channel, DataChannelInterface::DataState state) { - RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUN_ON(network_thread()); + + // Stash away the internal id here in case `OnSctpDataChannelClosed` ends up + // releasing the last reference to the channel. + const int channel_id = channel->internal_id(); + if (state == DataChannelInterface::DataState::kClosed) OnSctpDataChannelClosed(channel); - pc_->OnSctpDataChannelStateChanged(channel, state); + signaling_thread()->PostTask( + SafeTask(signaling_safety_.flag(), [this, channel_id, state = state] { + pc_->OnSctpDataChannelStateChanged(channel_id, state); + })); } void DataChannelController::OnDataReceived( @@ -87,111 +100,106 @@ void DataChannelController::OnDataReceived( if (HandleOpenMessage_n(channel_id, type, buffer)) return; - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), [this, channel_id, type, buffer] { - RTC_DCHECK_RUN_ON(signaling_thread()); - // TODO(bugs.webrtc.org/11547): The data being received should be - // delivered on the network thread. - auto it = FindChannel(StreamId(channel_id)); - if (it != sctp_data_channels_.end()) - (*it)->OnDataReceived(type, buffer); - })); + auto it = absl::c_find_if(sctp_data_channels_n_, [&](const auto& c) { + return c->sid_n().stream_id_int() == channel_id; + }); + + if (it != sctp_data_channels_n_.end()) + (*it)->OnDataReceived(type, buffer); } void DataChannelController::OnChannelClosing(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), [this, channel_id] { - RTC_DCHECK_RUN_ON(signaling_thread()); - // TODO(bugs.webrtc.org/11547): Should run on the network thread. - auto it = FindChannel(StreamId(channel_id)); - if (it != sctp_data_channels_.end()) - (*it)->OnClosingProcedureStartedRemotely(); - })); + auto it = absl::c_find_if(sctp_data_channels_n_, [&](const auto& c) { + return c->sid_n().stream_id_int() == channel_id; + }); + + if (it != sctp_data_channels_n_.end()) + (*it)->OnClosingProcedureStartedRemotely(); } void DataChannelController::OnChannelClosed(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), [this, channel_id] { - RTC_DCHECK_RUN_ON(signaling_thread()); - auto it = FindChannel(StreamId(channel_id)); - // Remove the channel from our list, close it and free up resources. - if (it != sctp_data_channels_.end()) { - rtc::scoped_refptr channel = std::move(*it); - // Note: this causes OnSctpDataChannelClosed() to not do anything - // when called from within `OnClosingProcedureComplete`. - sctp_data_channels_.erase(it); - sid_allocator_.ReleaseSid(channel->sid()); - - channel->OnClosingProcedureComplete(); - } - })); + StreamId sid(channel_id); + sid_allocator_.ReleaseSid(sid); + auto it = absl::c_find_if(sctp_data_channels_n_, + [&](const auto& c) { return c->sid_n() == sid; }); + + if (it != sctp_data_channels_n_.end()) { + rtc::scoped_refptr channel = std::move(*it); + sctp_data_channels_n_.erase(it); + channel->OnClosingProcedureComplete(); + } } void DataChannelController::OnReadyToSend() { RTC_DCHECK_RUN_ON(network_thread()); - signaling_thread()->PostTask(SafeTask(signaling_safety_.flag(), [this] { - RTC_DCHECK_RUN_ON(signaling_thread()); - data_channel_transport_ready_to_send_ = true; - auto copy = sctp_data_channels_; - for (const auto& channel : copy) + auto copy = sctp_data_channels_n_; + for (const auto& channel : copy) { + if (channel->sid_n().HasValue()) { channel->OnTransportReady(); - })); + } else { + // This happens for role==SSL_SERVER channels when we get notified by + // the transport *before* the SDP code calls `AllocateSctpSids` to + // trigger assignment of sids. In this case OnTransportReady() will be + // called from within `AllocateSctpSids` below. + RTC_LOG(LS_INFO) << "OnReadyToSend: Still waiting for an id for channel."; + } + } } void DataChannelController::OnTransportClosed(RTCError error) { RTC_DCHECK_RUN_ON(network_thread()); - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), [this, error] { - RTC_DCHECK_RUN_ON(signaling_thread()); - OnTransportChannelClosed(error); - })); + + // This loop will close all data channels and trigger a callback to + // `OnSctpDataChannelClosed`. We'll empty `sctp_data_channels_n_`, first + // and `OnSctpDataChannelClosed` will become a noop but we'll release the + // StreamId here. + std::vector> temp_sctp_dcs; + temp_sctp_dcs.swap(sctp_data_channels_n_); + for (const auto& channel : temp_sctp_dcs) { + channel->OnTransportChannelClosed(error); + sid_allocator_.ReleaseSid(channel->sid_n()); + } } -void DataChannelController::SetupDataChannelTransport_n() { +void DataChannelController::SetupDataChannelTransport_n( + DataChannelTransportInterface* transport) { RTC_DCHECK_RUN_ON(network_thread()); + RTC_DCHECK(transport); + set_data_channel_transport(transport); +} - // There's a new data channel transport. This needs to be signaled to the - // `sctp_data_channels_` so that they can reopen and reconnect. This is - // necessary when bundling is applied. - NotifyDataChannelsOfTransportCreated(); +void DataChannelController::PrepareForShutdown() { + RTC_DCHECK_RUN_ON(signaling_thread()); + signaling_safety_.reset(PendingTaskSafetyFlag::CreateDetachedInactive()); } -void DataChannelController::TeardownDataChannelTransport_n() { +void DataChannelController::TeardownDataChannelTransport_n(RTCError error) { RTC_DCHECK_RUN_ON(network_thread()); - if (data_channel_transport()) { - data_channel_transport()->SetDataSink(nullptr); - } + OnTransportClosed(error); set_data_channel_transport(nullptr); + RTC_DCHECK(sctp_data_channels_n_.empty()); + weak_factory_.InvalidateWeakPtrs(); } void DataChannelController::OnTransportChanged( DataChannelTransportInterface* new_data_channel_transport) { RTC_DCHECK_RUN_ON(network_thread()); - if (data_channel_transport() && - data_channel_transport() != new_data_channel_transport) { + if (data_channel_transport_ && + data_channel_transport_ != new_data_channel_transport) { // Changed which data channel transport is used for `sctp_mid_` (eg. now // it's bundled). - data_channel_transport()->SetDataSink(nullptr); set_data_channel_transport(new_data_channel_transport); - if (new_data_channel_transport) { - new_data_channel_transport->SetDataSink(this); - - // There's a new data channel transport. This needs to be signaled to the - // `sctp_data_channels_` so that they can reopen and reconnect. This is - // necessary when bundling is applied. - NotifyDataChannelsOfTransportCreated(); - } } } std::vector DataChannelController::GetDataChannelStats() const { - RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUN_ON(network_thread()); std::vector stats; - stats.reserve(sctp_data_channels_.size()); - for (const auto& channel : sctp_data_channels_) + stats.reserve(sctp_data_channels_n_.size()); + for (const auto& channel : sctp_data_channels_n_) stats.push_back(channel->GetStats()); return stats; } @@ -213,131 +221,165 @@ bool DataChannelController::HandleOpenMessage_n( << channel_id; } else { config.open_handshake_role = InternalDataChannelInit::kAcker; - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), - [this, label = std::move(label), config = std::move(config)] { - RTC_DCHECK_RUN_ON(signaling_thread()); - OnDataChannelOpenMessage(label, config); - })); + auto channel_or_error = CreateDataChannel(label, config); + if (channel_or_error.ok()) { + signaling_thread()->PostTask(SafeTask( + signaling_safety_.flag(), + [this, channel = channel_or_error.MoveValue(), + ready_to_send = data_channel_transport_->IsReadyToSend()] { + RTC_DCHECK_RUN_ON(signaling_thread()); + OnDataChannelOpenMessage(std::move(channel), ready_to_send); + })); + } else { + RTC_LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message." + << ToString(channel_or_error.error().type()); + } } return true; } void DataChannelController::OnDataChannelOpenMessage( - const std::string& label, - const InternalDataChannelInit& config) { - rtc::scoped_refptr channel( - InternalCreateDataChannelWithProxy(label, &config)); - if (!channel.get()) { - RTC_LOG(LS_ERROR) << "Failed to create DataChannel from the OPEN message."; - return; - } + rtc::scoped_refptr channel, + bool ready_to_send) { + has_used_data_channels_ = true; + auto proxy = SctpDataChannel::CreateProxy(channel, signaling_safety_.flag()); - pc_->Observer()->OnDataChannel(std::move(channel)); + pc_->Observer()->OnDataChannel(proxy); pc_->NoteDataAddedEvent(); + + if (ready_to_send) { + network_thread()->PostTask([channel = std::move(channel)] { + if (channel->state() != DataChannelInterface::DataState::kClosed) + channel->OnTransportReady(); + }); + } } -rtc::scoped_refptr -DataChannelController::InternalCreateDataChannelWithProxy( - const std::string& label, - const InternalDataChannelInit* config) { - RTC_DCHECK_RUN_ON(signaling_thread()); - if (pc_->IsClosed()) { - return nullptr; +// RTC_RUN_ON(network_thread()) +RTCError DataChannelController::ReserveOrAllocateSid( + StreamId& sid, + absl::optional fallback_ssl_role) { + if (sid.HasValue()) { + return sid_allocator_.ReserveSid(sid) + ? RTCError::OK() + : RTCError(RTCErrorType::INVALID_RANGE, + "StreamId out of range or reserved."); } - rtc::scoped_refptr channel = - InternalCreateSctpDataChannel(label, config); - if (channel) { - return SctpDataChannel::CreateProxy(channel); + // Attempt to allocate an ID based on the negotiated role. + absl::optional role = pc_->GetSctpSslRole_n(); + if (!role) + role = fallback_ssl_role; + if (role) { + sid = sid_allocator_.AllocateSid(*role); + if (!sid.HasValue()) + return RTCError(RTCErrorType::RESOURCE_EXHAUSTED); } + // When we get here, we may still not have an ID, but that's a supported case + // whereby an id will be assigned later. + RTC_DCHECK(sid.HasValue() || !role); + return RTCError::OK(); +} + +// RTC_RUN_ON(network_thread()) +RTCErrorOr> +DataChannelController::CreateDataChannel(const std::string& label, + InternalDataChannelInit& config) { + StreamId sid(config.id); + RTCError err = ReserveOrAllocateSid(sid, config.fallback_ssl_role); + if (!err.ok()) + return err; + + // In case `sid` has changed. Update `config` accordingly. + config.id = sid.stream_id_int(); + + rtc::scoped_refptr channel = SctpDataChannel::Create( + weak_factory_.GetWeakPtr(), label, data_channel_transport_ != nullptr, + config, signaling_thread(), network_thread()); + RTC_DCHECK(channel); + sctp_data_channels_n_.push_back(channel); + + // If we have an id already, notify the transport. + if (sid.HasValue()) + AddSctpDataStream(sid); - return nullptr; + return channel; } -rtc::scoped_refptr -DataChannelController::InternalCreateSctpDataChannel( +RTCErrorOr> +DataChannelController::InternalCreateDataChannelWithProxy( const std::string& label, - const InternalDataChannelInit* config) { + const InternalDataChannelInit& config) { RTC_DCHECK_RUN_ON(signaling_thread()); - if (config && !config->IsValid()) { - RTC_LOG(LS_ERROR) << "Failed to initialize the SCTP data channel due to " - "invalid DataChannelInit."; - return nullptr; + RTC_DCHECK(!pc_->IsClosed()); + if (!config.IsValid()) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, + "Invalid DataChannelInit"); } - InternalDataChannelInit new_config = - config ? (*config) : InternalDataChannelInit(); + bool ready_to_send = false; + InternalDataChannelInit new_config = config; StreamId sid(new_config.id); - if (!sid.HasValue()) { - rtc::SSLRole role; - // TODO(bugs.webrtc.org/11547): `GetSctpSslRole` likely involves a hop to - // the network thread. (unless there's no transport). Change this so that - // the role is checked on the network thread and any network thread related - // initialization is done at the same time (to avoid additional hops). - // Use `GetSctpSslRole_n` on the network thread. - if (pc_->GetSctpSslRole(&role)) { - sid = sid_allocator_.AllocateSid(role); - if (!sid.HasValue()) - return nullptr; - } - // Note that when we get here, the ID may still be invalid. - } else if (!sid_allocator_.ReserveSid(sid)) { - RTC_LOG(LS_ERROR) << "Failed to create a SCTP data channel " - "because the id is already in use or out of range."; - return nullptr; - } - // In case `sid` has changed. Update `new_config` accordingly. - new_config.id = sid.stream_id_int(); - // TODO(bugs.webrtc.org/11547): The `data_channel_transport_` pointer belongs - // to the network thread but there are a few places where we check this - // pointer from the signaling thread. Instead of this approach, we should have - // a separate channel initialization step that runs on the network thread - // where we inform the channel of information about whether there's a - // transport or not, what the role is, and supply an id if any. Subsequently - // all that state in the channel code, is needed for callbacks from the - // transport which is already initiated from the network thread. Then we can - // Remove the trampoline code (see e.g. PostTask() calls in this file) that - // travels between the signaling and network threads. - rtc::scoped_refptr channel(SctpDataChannel::Create( - weak_factory_.GetWeakPtr(), label, data_channel_transport() != nullptr, - new_config, signaling_thread(), network_thread())); - RTC_DCHECK(channel); + auto ret = network_thread()->BlockingCall( + [&]() -> RTCErrorOr> { + RTC_DCHECK_RUN_ON(network_thread()); + auto channel = CreateDataChannel(label, new_config); + if (!channel.ok()) + return channel; + ready_to_send = + data_channel_transport_ && data_channel_transport_->IsReadyToSend(); + if (ready_to_send) { + // If the transport is ready to send because the initial channel + // ready signal may have been sent before the DataChannel creation. + // This has to be done async because the upper layer objects (e.g. + // Chrome glue and WebKit) are not wired up properly until after + // `InternalCreateDataChannelWithProxy` returns. + network_thread()->PostTask([channel = channel.value()] { + if (channel->state() != DataChannelInterface::DataState::kClosed) + channel->OnTransportReady(); + }); + } - if (ReadyToSendData()) { - // Checks if the transport is ready to send because the initial channel - // ready signal may have been sent before the DataChannel creation. - // This has to be done async because the upper layer objects (e.g. - // Chrome glue and WebKit) are not wired up properly until after this - // function returns. - signaling_thread()->PostTask( - SafeTask(signaling_safety_.flag(), [channel = channel] { - if (channel->state() != DataChannelInterface::DataState::kClosed) - channel->OnTransportReady(); - })); - } + return channel; + }); + + if (!ret.ok()) + return ret.MoveError(); - sctp_data_channels_.push_back(channel); has_used_data_channels_ = true; - return channel; + return SctpDataChannel::CreateProxy(ret.MoveValue(), + signaling_safety_.flag()); } void DataChannelController::AllocateSctpSids(rtc::SSLRole role) { - RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUN_ON(network_thread()); + + const bool ready_to_send = + data_channel_transport_ && data_channel_transport_->IsReadyToSend(); + + std::vector> channels_to_update; std::vector> channels_to_close; - for (const auto& channel : sctp_data_channels_) { - if (!channel->sid().HasValue()) { + for (auto it = sctp_data_channels_n_.begin(); + it != sctp_data_channels_n_.end();) { + if (!(*it)->sid_n().HasValue()) { StreamId sid = sid_allocator_.AllocateSid(role); - if (!sid.HasValue()) { - channels_to_close.push_back(channel); + if (sid.HasValue()) { + (*it)->SetSctpSid_n(sid); + AddSctpDataStream(sid); + if (ready_to_send) { + RTC_LOG(LS_INFO) << "AllocateSctpSids: Id assigned, ready to send."; + (*it)->OnTransportReady(); + } + channels_to_update.push_back(std::make_pair((*it).get(), sid)); + } else { + channels_to_close.push_back(std::move(*it)); + it = sctp_data_channels_n_.erase(it); continue; } - // TODO(bugs.webrtc.org/11547): This hides a blocking call to the network - // thread via AddSctpDataStream. Maybe it's better to move the whole loop - // to the network thread? Maybe even `sctp_data_channels_`? - channel->SetSctpSid(sid); } + ++it; } + // Since closing modifies the list of channels, we have to do the actual // closing outside the loop. for (const auto& channel : channels_to_close) { @@ -346,96 +388,51 @@ void DataChannelController::AllocateSctpSids(rtc::SSLRole role) { } void DataChannelController::OnSctpDataChannelClosed(SctpDataChannel* channel) { - RTC_DCHECK_RUN_ON(signaling_thread()); - for (auto it = sctp_data_channels_.begin(); it != sctp_data_channels_.end(); - ++it) { - if (it->get() == channel) { - if (channel->sid().HasValue()) { - // After the closing procedure is done, it's safe to use this ID for - // another data channel. - sid_allocator_.ReleaseSid(channel->sid()); - } - - // Since this method is triggered by a signal from the DataChannel, - // we can't free it directly here; we need to free it asynchronously. - rtc::scoped_refptr release = std::move(*it); - sctp_data_channels_.erase(it); - signaling_thread()->PostTask(SafeTask(signaling_safety_.flag(), - [release = std::move(release)] {})); - return; - } - } -} - -void DataChannelController::OnTransportChannelClosed(RTCError error) { - RTC_DCHECK_RUN_ON(signaling_thread()); - // Use a temporary copy of the SCTP DataChannel list because the - // DataChannel may callback to us and try to modify the list. - // TODO(tommi): `OnTransportChannelClosed` is called from - // `SdpOfferAnswerHandler::DestroyDataChannelTransport` just before - // `TeardownDataChannelTransport_n` is called (but on the network thread) from - // the same function. Once `sctp_data_channels_` moves to the network thread, - // we can get rid of this function (OnTransportChannelClosed) and run this - // loop from within the TeardownDataChannelTransport_n callback. - std::vector> temp_sctp_dcs; - temp_sctp_dcs.swap(sctp_data_channels_); - for (const auto& channel : temp_sctp_dcs) { - channel->OnTransportChannelClosed(error); + RTC_DCHECK_RUN_ON(network_thread()); + // After the closing procedure is done, it's safe to use this ID for + // another data channel. + if (channel->sid_n().HasValue()) { + sid_allocator_.ReleaseSid(channel->sid_n()); } -} - -DataChannelTransportInterface* DataChannelController::data_channel_transport() - const { - // TODO(bugs.webrtc.org/11547): Only allow this accessor to be called on the - // network thread. - // RTC_DCHECK_RUN_ON(network_thread()); - return data_channel_transport_; + auto it = absl::c_find_if(sctp_data_channels_n_, + [&](const auto& c) { return c.get() == channel; }); + if (it != sctp_data_channels_n_.end()) + sctp_data_channels_n_.erase(it); } void DataChannelController::set_data_channel_transport( DataChannelTransportInterface* transport) { RTC_DCHECK_RUN_ON(network_thread()); - data_channel_transport_ = transport; -} -RTCError DataChannelController::DataChannelSendData( - StreamId sid, - const SendDataParams& params, - const rtc::CopyOnWriteBuffer& payload) { - // TODO(bugs.webrtc.org/11547): Expect method to be called on the network - // thread instead. Remove the BlockingCall() below and move associated state - // to the network thread. - RTC_DCHECK_RUN_ON(signaling_thread()); - RTC_DCHECK(data_channel_transport()); + if (data_channel_transport_) + data_channel_transport_->SetDataSink(nullptr); - return network_thread()->BlockingCall([this, sid, params, payload] { - return data_channel_transport()->SendData(sid.stream_id_int(), params, - payload); - }); + data_channel_transport_ = transport; + + if (data_channel_transport_) { + // There's a new data channel transport. This needs to be signaled to the + // `sctp_data_channels_n_` so that they can reopen and reconnect. This is + // necessary when bundling is applied. + NotifyDataChannelsOfTransportCreated(); + data_channel_transport_->SetDataSink(this); + } } void DataChannelController::NotifyDataChannelsOfTransportCreated() { RTC_DCHECK_RUN_ON(network_thread()); - RTC_DCHECK(data_channel_transport()); - signaling_thread()->PostTask(SafeTask(signaling_safety_.flag(), [this] { - RTC_DCHECK_RUN_ON(signaling_thread()); - auto copy = sctp_data_channels_; - for (const auto& channel : copy) { - channel->OnTransportChannelCreated(); - } - })); -} + RTC_DCHECK(data_channel_transport_); -std::vector>::iterator -DataChannelController::FindChannel(StreamId stream_id) { - RTC_DCHECK_RUN_ON(signaling_thread()); - return absl::c_find_if(sctp_data_channels_, - [&](const auto& c) { return c->sid() == stream_id; }); + for (const auto& channel : sctp_data_channels_n_) { + if (channel->sid_n().HasValue()) + AddSctpDataStream(channel->sid_n()); + channel->OnTransportChannelCreated(); + } } rtc::Thread* DataChannelController::network_thread() const { return pc_->network_thread(); } + rtc::Thread* DataChannelController::signaling_thread() const { return pc_->signaling_thread(); } diff --git a/third_party/libwebrtc/pc/data_channel_controller.h b/third_party/libwebrtc/pc/data_channel_controller.h index 6275d6249ed39..1b5c8beadb11a 100644 --- a/third_party/libwebrtc/pc/data_channel_controller.h +++ b/third_party/libwebrtc/pc/data_channel_controller.h @@ -52,7 +52,6 @@ class DataChannelController : public SctpDataChannelControllerInterface, const rtc::CopyOnWriteBuffer& payload) override; void AddSctpDataStream(StreamId sid) override; void RemoveSctpDataStream(StreamId sid) override; - bool ReadyToSendData() const override; void OnChannelStateChanged(SctpDataChannel* channel, DataChannelInterface::DataState state) override; @@ -65,10 +64,13 @@ class DataChannelController : public SctpDataChannelControllerInterface, void OnReadyToSend() override; void OnTransportClosed(RTCError error) override; + // Called as part of destroying the owning PeerConnection. + void PrepareForShutdown(); + // Called from PeerConnection::SetupDataChannelTransport_n - void SetupDataChannelTransport_n(); + void SetupDataChannelTransport_n(DataChannelTransportInterface* transport); // Called from PeerConnection::TeardownDataChannelTransport_n - void TeardownDataChannelTransport_n(); + void TeardownDataChannelTransport_n(RTCError error); // Called from PeerConnection::OnTransportChanged // to make required changes to datachannels' transports. @@ -80,32 +82,29 @@ class DataChannelController : public SctpDataChannelControllerInterface, // Creates channel and adds it to the collection of DataChannels that will // be offered in a SessionDescription, and wraps it in a proxy object. - rtc::scoped_refptr InternalCreateDataChannelWithProxy( - const std::string& label, - const InternalDataChannelInit* - config) /* RTC_RUN_ON(signaling_thread()) */; + RTCErrorOr> + InternalCreateDataChannelWithProxy(const std::string& label, + const InternalDataChannelInit& config); void AllocateSctpSids(rtc::SSLRole role); - // Checks if any data channel has been added. - // A data channel currently exist. + // Check if data channels are currently tracked. Used to decide whether a + // rejected m=application section should be reoffered. bool HasDataChannels() const; + // At some point in time, a data channel has existed. bool HasUsedDataChannels() const; - // Accessors - DataChannelTransportInterface* data_channel_transport() const; - void set_data_channel_transport(DataChannelTransportInterface* transport); - - // Called when the transport for the data channels is closed or destroyed. - void OnTransportChannelClosed(RTCError error); - void OnSctpDataChannelClosed(SctpDataChannel* channel); + protected: + rtc::Thread* network_thread() const; + rtc::Thread* signaling_thread() const; + private: - rtc::scoped_refptr InternalCreateSctpDataChannel( + // Creates a new SctpDataChannel object on the network thread. + RTCErrorOr> CreateDataChannel( const std::string& label, - const InternalDataChannelInit* - config) /* RTC_RUN_ON(signaling_thread()) */; + InternalDataChannelInit& config) RTC_RUN_ON(network_thread()); // Parses and handles open messages. Returns true if the message is an open // message and should be considered to be handled, false otherwise. @@ -114,46 +113,44 @@ class DataChannelController : public SctpDataChannelControllerInterface, const rtc::CopyOnWriteBuffer& buffer) RTC_RUN_ON(network_thread()); // Called when a valid data channel OPEN message is received. - void OnDataChannelOpenMessage(const std::string& label, - const InternalDataChannelInit& config) + void OnDataChannelOpenMessage(rtc::scoped_refptr channel, + bool ready_to_send) RTC_RUN_ON(signaling_thread()); - // Called from SendData when data_channel_transport() is true. - RTCError DataChannelSendData(StreamId sid, - const SendDataParams& params, - const rtc::CopyOnWriteBuffer& payload); + // Accepts a `StreamId` which may be pre-negotiated or unassigned. For + // pre-negotiated sids, attempts to reserve the sid in the allocation pool, + // for unassigned sids attempts to generate a new sid if possible. Returns + // RTCError::OK() if the sid is reserved (and may have been generated) or + // if not enough information exists to generate a sid, in which case the sid + // will still be unassigned upon return, but will be assigned later. + // If the pool has been exhausted or a sid has already been reserved, an + // error will be returned. + RTCError ReserveOrAllocateSid(StreamId& sid, + absl::optional fallback_ssl_role) + RTC_RUN_ON(network_thread()); // Called when all data channels need to be notified of a transport channel // (calls OnTransportChannelCreated on the signaling thread). void NotifyDataChannelsOfTransportCreated(); - std::vector>::iterator FindChannel( - StreamId stream_id); - - rtc::Thread* network_thread() const; - rtc::Thread* signaling_thread() const; + void set_data_channel_transport(DataChannelTransportInterface* transport); // Plugin transport used for data channels. Pointer may be accessed and // checked from any thread, but the object may only be touched on the // network thread. - // TODO(bugs.webrtc.org/9987): Accessed on both signaling and network - // thread. - DataChannelTransportInterface* data_channel_transport_ = nullptr; - - // Cached value of whether the data channel transport is ready to send. - bool data_channel_transport_ready_to_send_ - RTC_GUARDED_BY(signaling_thread()) = false; - - SctpSidAllocator sid_allocator_; - std::vector> sctp_data_channels_ - RTC_GUARDED_BY(signaling_thread()); + DataChannelTransportInterface* data_channel_transport_ + RTC_GUARDED_BY(network_thread()) = nullptr; + SctpSidAllocator sid_allocator_ RTC_GUARDED_BY(network_thread()); + std::vector> sctp_data_channels_n_ + RTC_GUARDED_BY(network_thread()); bool has_used_data_channels_ RTC_GUARDED_BY(signaling_thread()) = false; // Owning PeerConnection. PeerConnectionInternal* const pc_; - // The weak pointers must be dereferenced and invalidated on the signalling + // The weak pointers must be dereferenced and invalidated on the network // thread only. - rtc::WeakPtrFactory weak_factory_{this}; + rtc::WeakPtrFactory weak_factory_ + RTC_GUARDED_BY(network_thread()){this}; ScopedTaskSafety signaling_safety_; }; diff --git a/third_party/libwebrtc/pc/data_channel_controller_unittest.cc b/third_party/libwebrtc/pc/data_channel_controller_unittest.cc index 1e575e60e940b..3b8adb6819814 100644 --- a/third_party/libwebrtc/pc/data_channel_controller_unittest.cc +++ b/third_party/libwebrtc/pc/data_channel_controller_unittest.cc @@ -15,6 +15,7 @@ #include "pc/peer_connection_internal.h" #include "pc/sctp_data_channel.h" #include "pc/test/mock_peer_connection_internal.h" +#include "rtc_base/null_socket_server.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/run_loop.h" @@ -42,136 +43,172 @@ class MockDataChannelTransport : public webrtc::DataChannelTransportInterface { MOCK_METHOD(bool, IsReadyToSend, (), (const, override)); }; +// Convenience class for tests to ensure that shutdown methods for DCC +// are consistently called. In practice SdpOfferAnswerHandler will call +// TeardownDataChannelTransport_n on the network thread when destroying the +// data channel transport and PeerConnection calls PrepareForShutdown() from +// within PeerConnection::Close(). The DataChannelControllerForTest class mimics +// behavior by calling those methods from within its destructor. +class DataChannelControllerForTest : public DataChannelController { + public: + explicit DataChannelControllerForTest( + PeerConnectionInternal* pc, + DataChannelTransportInterface* transport = nullptr) + : DataChannelController(pc) { + if (transport) { + network_thread()->BlockingCall( + [&] { SetupDataChannelTransport_n(transport); }); + } + } + + ~DataChannelControllerForTest() override { + network_thread()->BlockingCall( + [&] { TeardownDataChannelTransport_n(RTCError::OK()); }); + PrepareForShutdown(); + } +}; + class DataChannelControllerTest : public ::testing::Test { protected: - DataChannelControllerTest() { + DataChannelControllerTest() + : network_thread_(std::make_unique()) { + network_thread_.Start(); pc_ = rtc::make_ref_counted>(); ON_CALL(*pc_, signaling_thread) .WillByDefault(Return(rtc::Thread::Current())); - // TODO(tommi): Return a dedicated thread. - ON_CALL(*pc_, network_thread).WillByDefault(Return(rtc::Thread::Current())); + ON_CALL(*pc_, network_thread).WillByDefault(Return(&network_thread_)); } - ~DataChannelControllerTest() override { run_loop_.Flush(); } + ~DataChannelControllerTest() override { + run_loop_.Flush(); + network_thread_.Stop(); + } test::RunLoop run_loop_; + rtc::Thread network_thread_; rtc::scoped_refptr> pc_; }; TEST_F(DataChannelControllerTest, CreateAndDestroy) { - DataChannelController dcc(pc_.get()); + DataChannelControllerForTest dcc(pc_.get()); } TEST_F(DataChannelControllerTest, CreateDataChannelEarlyRelease) { - DataChannelController dcc(pc_.get()); - auto channel = dcc.InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); - channel = nullptr; // dcc holds a reference to channel, so not destroyed yet + DataChannelControllerForTest dcc(pc_.get()); + auto ret = dcc.InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())); + ASSERT_TRUE(ret.ok()); + auto channel = ret.MoveValue(); + // DCC still holds a reference to the channel. Release this reference early. + channel = nullptr; } TEST_F(DataChannelControllerTest, CreateDataChannelEarlyClose) { - DataChannelController dcc(pc_.get()); + DataChannelControllerForTest dcc(pc_.get()); EXPECT_FALSE(dcc.HasDataChannels()); EXPECT_FALSE(dcc.HasUsedDataChannels()); - auto channel = dcc.InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); + auto ret = dcc.InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())); + ASSERT_TRUE(ret.ok()); + auto channel = ret.MoveValue(); EXPECT_TRUE(dcc.HasDataChannels()); EXPECT_TRUE(dcc.HasUsedDataChannels()); channel->Close(); + run_loop_.Flush(); EXPECT_FALSE(dcc.HasDataChannels()); EXPECT_TRUE(dcc.HasUsedDataChannels()); } TEST_F(DataChannelControllerTest, CreateDataChannelLateRelease) { - auto dcc = std::make_unique(pc_.get()); - auto channel = dcc->InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); + auto dcc = std::make_unique(pc_.get()); + auto ret = dcc->InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())); + ASSERT_TRUE(ret.ok()); + auto channel = ret.MoveValue(); dcc.reset(); channel = nullptr; } TEST_F(DataChannelControllerTest, CloseAfterControllerDestroyed) { - auto dcc = std::make_unique(pc_.get()); - auto channel = dcc->InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); + auto dcc = std::make_unique(pc_.get()); + auto ret = dcc->InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())); + ASSERT_TRUE(ret.ok()); + auto channel = ret.MoveValue(); dcc.reset(); channel->Close(); } -TEST_F(DataChannelControllerTest, AsyncChannelCloseTeardown) { - DataChannelController dcc(pc_.get()); - rtc::scoped_refptr channel = - dcc.InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); - SctpDataChannel* inner_channel = - DowncastProxiedDataChannelInterfaceToSctpDataChannelForTesting( - channel.get()); - // Grab a reference for testing purposes. - inner_channel->AddRef(); - - channel = nullptr; // dcc still holds a reference to `channel`. - EXPECT_TRUE(dcc.HasDataChannels()); - - // Trigger a Close() for the channel. This will send events back to dcc, - // eventually reaching `OnSctpDataChannelClosed` where dcc removes - // the channel from the internal list of data channels, but does not release - // the reference synchronously since that reference might be the last one. - inner_channel->Close(); - // Now there should be no tracked data channels. - EXPECT_FALSE(dcc.HasDataChannels()); - // But there should be an async operation queued that still holds a reference. - // That means that the test reference, must not be the last one. - ASSERT_NE(inner_channel->Release(), - rtc::RefCountReleaseStatus::kDroppedLastRef); - // Grab a reference again (using the pointer is safe since the object still - // exists and we control the single-threaded environment manually). - inner_channel->AddRef(); - // Now run the queued up async operations on the signaling (current) thread. - // This time, the reference formerly owned by dcc, should be release and the - // truly last reference is now held by the test. - run_loop_.Flush(); - // Check that this is the last reference. - EXPECT_EQ(inner_channel->Release(), - rtc::RefCountReleaseStatus::kDroppedLastRef); -} - // Allocate the maximum number of data channels and then one more. // The last allocation should fail. TEST_F(DataChannelControllerTest, MaxChannels) { NiceMock transport; int channel_id = 0; - ON_CALL(*pc_, GetSctpSslRole).WillByDefault([&](rtc::SSLRole* role) { - *role = (channel_id & 1) ? rtc::SSL_SERVER : rtc::SSL_CLIENT; - return true; + ON_CALL(*pc_, GetSctpSslRole_n).WillByDefault([&]() { + return absl::optional((channel_id & 1) ? rtc::SSL_SERVER + : rtc::SSL_CLIENT); }); - DataChannelController dcc(pc_.get()); - pc_->network_thread()->BlockingCall( - [&] { dcc.set_data_channel_transport(&transport); }); + DataChannelControllerForTest dcc(pc_.get(), &transport); // Allocate the maximum number of channels + 1. Inside the loop, the creation // process will allocate a stream id for each channel. for (channel_id = 0; channel_id <= cricket::kMaxSctpStreams; ++channel_id) { - rtc::scoped_refptr channel = - dcc.InternalCreateDataChannelWithProxy( - "label", - std::make_unique(DataChannelInit()).get()); - + auto ret = dcc.InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())); if (channel_id == cricket::kMaxSctpStreams) { // We've reached the maximum and the previous call should have failed. - EXPECT_FALSE(channel.get()); + EXPECT_FALSE(ret.ok()); } else { // We're still working on saturating the pool. Things should be working. - EXPECT_TRUE(channel.get()); + EXPECT_TRUE(ret.ok()); } } } +// Test that while a data channel is in the `kClosing` state, its StreamId does +// not get re-used for new channels. Only once the state reaches `kClosed` +// should a StreamId be available again for allocation. +TEST_F(DataChannelControllerTest, NoStreamIdReuseWhileClosing) { + ON_CALL(*pc_, GetSctpSslRole_n).WillByDefault([&]() { + return rtc::SSL_CLIENT; + }); + + NiceMock transport; // Wider scope than `dcc`. + DataChannelControllerForTest dcc(pc_.get(), &transport); + + // Create the first channel and check that we got the expected, first sid. + auto channel1 = dcc.InternalCreateDataChannelWithProxy( + "label", InternalDataChannelInit(DataChannelInit())) + .MoveValue(); + ASSERT_EQ(channel1->id(), 0); + + // Start closing the channel and make sure its state is `kClosing` + channel1->Close(); + ASSERT_EQ(channel1->state(), DataChannelInterface::DataState::kClosing); + + // Create a second channel and make sure we get a new StreamId, not the same + // as that of channel1. + auto channel2 = dcc.InternalCreateDataChannelWithProxy( + "label2", InternalDataChannelInit(DataChannelInit())) + .MoveValue(); + ASSERT_NE(channel2->id(), channel1->id()); // In practice the id will be 2. + + // Simulate the acknowledgement of the channel closing from the transport. + // This completes the closing operation of channel1. + pc_->network_thread()->BlockingCall([&] { dcc.OnChannelClosed(0); }); + run_loop_.Flush(); + ASSERT_EQ(channel1->state(), DataChannelInterface::DataState::kClosed); + + // Now create a third channel. This time, the id of the first channel should + // be available again and therefore the ids of the first and third channels + // should be the same. + auto channel3 = dcc.InternalCreateDataChannelWithProxy( + "label3", InternalDataChannelInit(DataChannelInit())) + .MoveValue(); + EXPECT_EQ(channel3->id(), channel1->id()); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/pc/data_channel_unittest.cc b/third_party/libwebrtc/pc/data_channel_unittest.cc index f92c05cca6d13..9b84a1be612fb 100644 --- a/third_party/libwebrtc/pc/data_channel_unittest.cc +++ b/third_party/libwebrtc/pc/data_channel_unittest.cc @@ -26,9 +26,15 @@ #include "pc/test/fake_data_channel_controller.h" #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/gunit.h" +#include "rtc_base/null_socket_server.h" #include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/thread.h" #include "test/gtest.h" +#include "test/run_loop.h" + +#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) +#include "test/testsupport/rtc_expect_death.h" +#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) namespace webrtc { @@ -38,18 +44,15 @@ static constexpr int kDefaultTimeout = 10000; class FakeDataChannelObserver : public DataChannelObserver { public: - FakeDataChannelObserver() - : messages_received_(0), - on_state_change_count_(0), - on_buffered_amount_change_count_(0) {} + FakeDataChannelObserver() { RTC_DCHECK(!IsOkToCallOnTheNetworkThread()); } - void OnStateChange() { ++on_state_change_count_; } + void OnStateChange() override { ++on_state_change_count_; } - void OnBufferedAmountChange(uint64_t previous_amount) { + void OnBufferedAmountChange(uint64_t previous_amount) override { ++on_buffered_amount_change_count_; } - void OnMessage(const DataBuffer& buffer) { ++messages_received_; } + void OnMessage(const DataBuffer& buffer) override { ++messages_received_; } size_t messages_received() const { return messages_received_; } @@ -66,64 +69,116 @@ class FakeDataChannelObserver : public DataChannelObserver { } private: - size_t messages_received_; - size_t on_state_change_count_; - size_t on_buffered_amount_change_count_; + size_t messages_received_ = 0u; + size_t on_state_change_count_ = 0u; + size_t on_buffered_amount_change_count_ = 0u; }; -// TODO(bugs.webrtc.org/11547): Incorporate a dedicated network thread. class SctpDataChannelTest : public ::testing::Test { protected: SctpDataChannelTest() - : controller_(new FakeDataChannelController()), - webrtc_data_channel_(controller_->CreateDataChannel("test", init_)) {} + : network_thread_(std::make_unique()), + controller_(new FakeDataChannelController(&network_thread_)) { + network_thread_.Start(); + inner_channel_ = controller_->CreateDataChannel("test", init_); + channel_ = + webrtc::SctpDataChannel::CreateProxy(inner_channel_, signaling_safety_); + } + ~SctpDataChannelTest() override { + run_loop_.Flush(); + signaling_safety_->SetNotAlive(); + inner_channel_ = nullptr; + channel_ = nullptr; + controller_.reset(); + observer_.reset(); + network_thread_.Stop(); + } void SetChannelReady() { controller_->set_transport_available(true); - webrtc_data_channel_->OnTransportChannelCreated(); - if (!webrtc_data_channel_->sid().HasValue()) { - webrtc_data_channel_->SetSctpSid(StreamId(0)); - } + StreamId sid(0); + network_thread_.BlockingCall([&]() { + RTC_DCHECK_RUN_ON(&network_thread_); + if (!inner_channel_->sid_n().HasValue()) { + inner_channel_->SetSctpSid_n(sid); + controller_->AddSctpDataStream(sid); + } + inner_channel_->OnTransportChannelCreated(); + }); controller_->set_ready_to_send(true); + run_loop_.Flush(); + } + + // TODO(bugs.webrtc.org/11547): This mirrors what the DataChannelController + // currently does when assigning stream ids to a channel. Right now the sid + // in the SctpDataChannel code is (still) tied to the signaling thread, but + // the `AddSctpDataStream` operation is a bridge to the transport and needs + // to run on the network thread. + void SetChannelSid(const rtc::scoped_refptr& channel, + StreamId sid) { + RTC_DCHECK(sid.HasValue()); + network_thread_.BlockingCall([&]() { + channel->SetSctpSid_n(sid); + controller_->AddSctpDataStream(sid); + }); } void AddObserver() { observer_.reset(new FakeDataChannelObserver()); - webrtc_data_channel_->RegisterObserver(observer_.get()); + channel_->RegisterObserver(observer_.get()); + } + + // Wait for queued up methods to run on the network thread. + void FlushNetworkThread() { + RTC_DCHECK_RUN_ON(run_loop_.task_queue()); + network_thread_.BlockingCall([] {}); + } + + // Used to complete pending methods on the network thread + // that might queue up methods on the signaling (main) thread + // that are run too. + void FlushNetworkThreadAndPendingOperations() { + FlushNetworkThread(); + run_loop_.Flush(); } - rtc::AutoThread main_thread_; + test::RunLoop run_loop_; + rtc::Thread network_thread_; InternalDataChannelInit init_; + rtc::scoped_refptr signaling_safety_ = + PendingTaskSafetyFlag::Create(); std::unique_ptr controller_; std::unique_ptr observer_; - rtc::scoped_refptr webrtc_data_channel_; + rtc::scoped_refptr inner_channel_; + rtc::scoped_refptr channel_; }; TEST_F(SctpDataChannelTest, VerifyConfigurationGetters) { - EXPECT_EQ(webrtc_data_channel_->label(), "test"); - EXPECT_EQ(webrtc_data_channel_->protocol(), init_.protocol); + EXPECT_EQ(channel_->label(), "test"); + EXPECT_EQ(channel_->protocol(), init_.protocol); // Note that the `init_.reliable` field is deprecated, so we directly set // it here to match spec behavior for purposes of checking the `reliable()` // getter. init_.reliable = (!init_.maxRetransmits && !init_.maxRetransmitTime); - EXPECT_EQ(webrtc_data_channel_->reliable(), init_.reliable); - EXPECT_EQ(webrtc_data_channel_->ordered(), init_.ordered); - EXPECT_EQ(webrtc_data_channel_->negotiated(), init_.negotiated); - EXPECT_EQ(webrtc_data_channel_->priority(), Priority::kLow); - EXPECT_EQ(webrtc_data_channel_->maxRetransmitTime(), - static_cast(-1)); - EXPECT_EQ(webrtc_data_channel_->maxPacketLifeTime(), init_.maxRetransmitTime); - EXPECT_EQ(webrtc_data_channel_->maxRetransmits(), static_cast(-1)); - EXPECT_EQ(webrtc_data_channel_->maxRetransmitsOpt(), init_.maxRetransmits); + EXPECT_EQ(channel_->reliable(), init_.reliable); + EXPECT_EQ(channel_->ordered(), init_.ordered); + EXPECT_EQ(channel_->negotiated(), init_.negotiated); + EXPECT_EQ(channel_->priority(), Priority::kLow); + EXPECT_EQ(channel_->maxRetransmitTime(), static_cast(-1)); + EXPECT_EQ(channel_->maxPacketLifeTime(), init_.maxRetransmitTime); + EXPECT_EQ(channel_->maxRetransmits(), static_cast(-1)); + EXPECT_EQ(channel_->maxRetransmitsOpt(), init_.maxRetransmits); // Check the non-const part of the configuration. - EXPECT_EQ(webrtc_data_channel_->id(), init_.id); - EXPECT_EQ(webrtc_data_channel_->sid(), StreamId()); + EXPECT_EQ(channel_->id(), init_.id); + network_thread_.BlockingCall( + [&]() { EXPECT_EQ(inner_channel_->sid_n(), StreamId()); }); SetChannelReady(); - EXPECT_EQ(webrtc_data_channel_->id(), 0); - EXPECT_EQ(webrtc_data_channel_->sid(), StreamId(0)); + EXPECT_EQ(channel_->id(), 0); + network_thread_.BlockingCall( + [&]() { EXPECT_EQ(inner_channel_->sid_n(), StreamId(0)); }); } // Verifies that the data channel is connected to the transport after creation. @@ -131,34 +186,40 @@ TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) { controller_->set_transport_available(true); rtc::scoped_refptr dc = controller_->CreateDataChannel("test1", init_); - EXPECT_TRUE(controller_->IsConnected(dc.get())); + // The sid is not set yet, so it should not have added the streams. - EXPECT_FALSE(controller_->IsStreamAdded(dc->sid())); + StreamId sid = network_thread_.BlockingCall([&]() { return dc->sid_n(); }); + EXPECT_FALSE(controller_->IsStreamAdded(sid)); - dc->SetSctpSid(StreamId(0)); - EXPECT_TRUE(controller_->IsStreamAdded(dc->sid())); + SetChannelSid(dc, StreamId(0)); + sid = network_thread_.BlockingCall([&]() { return dc->sid_n(); }); + EXPECT_TRUE(controller_->IsStreamAdded(sid)); } // Tests the state of the data channel. TEST_F(SctpDataChannelTest, StateTransition) { AddObserver(); - EXPECT_EQ(DataChannelInterface::kConnecting, webrtc_data_channel_->state()); + EXPECT_EQ(DataChannelInterface::kConnecting, channel_->state()); EXPECT_EQ(observer_->on_state_change_count(), 0u); SetChannelReady(); - EXPECT_EQ(DataChannelInterface::kOpen, webrtc_data_channel_->state()); + EXPECT_EQ(DataChannelInterface::kOpen, channel_->state()); EXPECT_EQ(observer_->on_state_change_count(), 1u); // `Close()` should trigger two state changes, first `kClosing`, then // `kClose`. - webrtc_data_channel_->Close(); - EXPECT_EQ(DataChannelInterface::kClosed, webrtc_data_channel_->state()); + channel_->Close(); + // The (simulated) transport close notifications runs on the network thread + // and posts a completion notification to the signaling (current) thread. + // Allow that operation to complete before checking the state. + run_loop_.Flush(); + EXPECT_EQ(DataChannelInterface::kClosed, channel_->state()); EXPECT_EQ(observer_->on_state_change_count(), 3u); - EXPECT_TRUE(webrtc_data_channel_->error().ok()); + EXPECT_TRUE(channel_->error().ok()); // Verifies that it's disconnected from the transport. - EXPECT_FALSE(controller_->IsConnected(webrtc_data_channel_.get())); + EXPECT_FALSE(controller_->IsConnected(inner_channel_.get())); } // Tests that DataChannel::buffered_amount() is correct after the channel is @@ -167,10 +228,53 @@ TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) { AddObserver(); SetChannelReady(); DataBuffer buffer("abcd"); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + size_t successful_sends = 0; + auto send_complete = [&](RTCError err) { + EXPECT_TRUE(err.ok()); + ++successful_sends; + }; + channel_->SendAsync(buffer, send_complete); + FlushNetworkThreadAndPendingOperations(); + EXPECT_EQ(channel_->buffered_amount(), 0u); size_t successful_send_count = 1; + EXPECT_EQ(successful_send_count, successful_sends); + EXPECT_EQ(successful_send_count, + observer_->on_buffered_amount_change_count()); - EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); + controller_->set_send_blocked(true); + const int number_of_packets = 3; + for (int i = 0; i < number_of_packets; ++i) { + channel_->SendAsync(buffer, send_complete); + ++successful_send_count; + } + FlushNetworkThreadAndPendingOperations(); + EXPECT_EQ(buffer.data.size() * number_of_packets, + channel_->buffered_amount()); + EXPECT_EQ(successful_send_count, successful_sends); + + // An event should not have been fired for buffered amount. + EXPECT_EQ(1u, observer_->on_buffered_amount_change_count()); + + // Now buffered amount events should get fired and the value + // get down to 0u. + controller_->set_send_blocked(false); + run_loop_.Flush(); + EXPECT_EQ(channel_->buffered_amount(), 0u); + EXPECT_EQ(successful_send_count, successful_sends); + EXPECT_EQ(successful_send_count, + observer_->on_buffered_amount_change_count()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedBufferedAmountWhenBlocked) { + AddObserver(); + SetChannelReady(); + DataBuffer buffer("abcd"); + EXPECT_TRUE(channel_->Send(buffer)); + size_t successful_send_count = 1; + + run_loop_.Flush(); + EXPECT_EQ(0U, channel_->buffered_amount()); EXPECT_EQ(successful_send_count, observer_->on_buffered_amount_change_count()); @@ -178,16 +282,17 @@ TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) { const int number_of_packets = 3; for (int i = 0; i < number_of_packets; ++i) { - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + EXPECT_TRUE(channel_->Send(buffer)); } EXPECT_EQ(buffer.data.size() * number_of_packets, - webrtc_data_channel_->buffered_amount()); + channel_->buffered_amount()); EXPECT_EQ(successful_send_count, observer_->on_buffered_amount_change_count()); controller_->set_send_blocked(false); + run_loop_.Flush(); successful_send_count += number_of_packets; - EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); + EXPECT_EQ(channel_->buffered_amount(), 0u); EXPECT_EQ(successful_send_count, observer_->on_buffered_amount_change_count()); } @@ -199,13 +304,35 @@ TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) { SetChannelReady(); DataBuffer buffer("abcd"); controller_->set_send_blocked(true); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + size_t successful_send = 0u; + auto send_complete = [&](RTCError err) { + EXPECT_TRUE(err.ok()); + ++successful_send; + }; + channel_->SendAsync(buffer, send_complete); + FlushNetworkThreadAndPendingOperations(); + EXPECT_EQ(1U, successful_send); + EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); + + controller_->set_send_blocked(false); + SetChannelReady(); + EXPECT_EQ(channel_->buffered_amount(), 0u); + EXPECT_EQ(observer_->on_buffered_amount_change_count(), 1u); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedQueuedDataSentWhenUnblocked) { + AddObserver(); + SetChannelReady(); + DataBuffer buffer("abcd"); + controller_->set_send_blocked(true); + EXPECT_TRUE(channel_->Send(buffer)); EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); controller_->set_send_blocked(false); SetChannelReady(); - EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); + EXPECT_EQ(0U, channel_->buffered_amount()); EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); } @@ -216,18 +343,46 @@ TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) { SetChannelReady(); DataBuffer buffer("abcd"); controller_->set_send_blocked(true); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + size_t successful_send = 0u; + auto send_complete = [&](RTCError err) { + EXPECT_TRUE(err.ok()); + ++successful_send; + }; + channel_->SendAsync(buffer, send_complete); + FlushNetworkThreadAndPendingOperations(); + EXPECT_EQ(1U, successful_send); EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); // Set channel ready while it is still blocked. SetChannelReady(); - EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount()); + EXPECT_EQ(buffer.size(), channel_->buffered_amount()); EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); // Unblock the channel to send queued data again, there should be no crash. controller_->set_send_blocked(false); SetChannelReady(); - EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); + EXPECT_EQ(0U, channel_->buffered_amount()); + EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedBlockedWhenSendQueuedDataNoCrash) { + AddObserver(); + SetChannelReady(); + DataBuffer buffer("abcd"); + controller_->set_send_blocked(true); + EXPECT_TRUE(channel_->Send(buffer)); + EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); + + // Set channel ready while it is still blocked. + SetChannelReady(); + EXPECT_EQ(buffer.size(), channel_->buffered_amount()); + EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); + + // Unblock the channel to send queued data again, there should be no crash. + controller_->set_send_blocked(false); + SetChannelReady(); + EXPECT_EQ(0U, channel_->buffered_amount()); EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); } @@ -246,48 +401,97 @@ TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesSent) { }); // Default values. - EXPECT_EQ(0U, webrtc_data_channel_->messages_sent()); - EXPECT_EQ(0U, webrtc_data_channel_->bytes_sent()); + EXPECT_EQ(0U, channel_->messages_sent()); + EXPECT_EQ(0U, channel_->bytes_sent()); + + // Send three buffers while not blocked. + controller_->set_send_blocked(false); + for (int i : {0, 1, 2}) { + channel_->SendAsync(buffers[i], nullptr); + } + FlushNetworkThreadAndPendingOperations(); + + size_t bytes_sent = buffers[0].size() + buffers[1].size() + buffers[2].size(); + EXPECT_EQ_WAIT(0U, channel_->buffered_amount(), kDefaultTimeout); + EXPECT_EQ(3U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); + + // Send three buffers while blocked, queuing the buffers. + controller_->set_send_blocked(true); + for (int i : {3, 4, 5}) { + channel_->SendAsync(buffers[i], nullptr); + } + FlushNetworkThreadAndPendingOperations(); + size_t bytes_queued = + buffers[3].size() + buffers[4].size() + buffers[5].size(); + EXPECT_EQ(bytes_queued, channel_->buffered_amount()); + EXPECT_EQ(3U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); + + // Unblock and make sure everything was sent. + controller_->set_send_blocked(false); + EXPECT_EQ_WAIT(0U, channel_->buffered_amount(), kDefaultTimeout); + bytes_sent += bytes_queued; + EXPECT_EQ(6U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedVerifyMessagesAndBytesSent) { + AddObserver(); + SetChannelReady(); + std::vector buffers({ + DataBuffer("message 1"), + DataBuffer("msg 2"), + DataBuffer("message three"), + DataBuffer("quadra message"), + DataBuffer("fifthmsg"), + DataBuffer("message of the beast"), + }); + + // Default values. + EXPECT_EQ(0U, channel_->messages_sent()); + EXPECT_EQ(0U, channel_->bytes_sent()); // Send three buffers while not blocked. controller_->set_send_blocked(false); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[0])); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[1])); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[2])); + EXPECT_TRUE(channel_->Send(buffers[0])); + EXPECT_TRUE(channel_->Send(buffers[1])); + EXPECT_TRUE(channel_->Send(buffers[2])); size_t bytes_sent = buffers[0].size() + buffers[1].size() + buffers[2].size(); - EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout); - EXPECT_EQ(3U, webrtc_data_channel_->messages_sent()); - EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); + EXPECT_EQ_WAIT(0U, channel_->buffered_amount(), kDefaultTimeout); + EXPECT_EQ(3U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); // Send three buffers while blocked, queuing the buffers. controller_->set_send_blocked(true); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[3])); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[4])); - EXPECT_TRUE(webrtc_data_channel_->Send(buffers[5])); + EXPECT_TRUE(channel_->Send(buffers[3])); + EXPECT_TRUE(channel_->Send(buffers[4])); + EXPECT_TRUE(channel_->Send(buffers[5])); size_t bytes_queued = buffers[3].size() + buffers[4].size() + buffers[5].size(); - EXPECT_EQ(bytes_queued, webrtc_data_channel_->buffered_amount()); - EXPECT_EQ(3U, webrtc_data_channel_->messages_sent()); - EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); + EXPECT_EQ(bytes_queued, channel_->buffered_amount()); + EXPECT_EQ(3U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); // Unblock and make sure everything was sent. controller_->set_send_blocked(false); - EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout); + EXPECT_EQ_WAIT(0U, channel_->buffered_amount(), kDefaultTimeout); bytes_sent += bytes_queued; - EXPECT_EQ(6U, webrtc_data_channel_->messages_sent()); - EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent()); + EXPECT_EQ(6U, channel_->messages_sent()); + EXPECT_EQ(bytes_sent, channel_->bytes_sent()); } // Tests that the queued control message is sent when channel is ready. TEST_F(SctpDataChannelTest, OpenMessageSent) { // Initially the id is unassigned. - EXPECT_EQ(-1, webrtc_data_channel_->id()); + EXPECT_EQ(-1, channel_->id()); SetChannelReady(); - EXPECT_GE(webrtc_data_channel_->id(), 0); + EXPECT_GE(channel_->id(), 0); EXPECT_EQ(DataMessageType::kControl, controller_->last_send_data_params().type); - EXPECT_EQ(controller_->last_sid(), webrtc_data_channel_->id()); + EXPECT_EQ(controller_->last_sid(), channel_->id()); } TEST_F(SctpDataChannelTest, QueuedOpenMessageSent) { @@ -297,7 +501,7 @@ TEST_F(SctpDataChannelTest, QueuedOpenMessageSent) { EXPECT_EQ(DataMessageType::kControl, controller_->last_send_data_params().type); - EXPECT_EQ(controller_->last_sid(), webrtc_data_channel_->id()); + EXPECT_EQ(controller_->last_sid(), channel_->id()); } // Tests that the DataChannel created after transport gets ready can enter OPEN @@ -306,10 +510,9 @@ TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) { SetChannelReady(); InternalDataChannelInit init; init.id = 1; - rtc::scoped_refptr dc = - controller_->CreateDataChannel("test1", init); - EXPECT_EQ(DataChannelInterface::kConnecting, dc->state()); - EXPECT_TRUE_WAIT(DataChannelInterface::kOpen == dc->state(), 1000); + auto dc = webrtc::SctpDataChannel::CreateProxy( + controller_->CreateDataChannel("test1", init), signaling_safety_); + EXPECT_EQ(DataChannelInterface::kOpen, dc->state()); } // Tests that an unordered DataChannel sends data as ordered until the OPEN_ACK @@ -321,21 +524,52 @@ TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) { init.ordered = false; rtc::scoped_refptr dc = controller_->CreateDataChannel("test1", init); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); + + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); + + // Sends a message and verifies it's ordered. + DataBuffer buffer("some data"); + proxy->SendAsync(buffer, nullptr); + EXPECT_TRUE(controller_->last_send_data_params().ordered); + + // Emulates receiving an OPEN_ACK message. + rtc::CopyOnWriteBuffer payload; + WriteDataChannelOpenAckMessage(&payload); + network_thread_.BlockingCall( + [&] { dc->OnDataReceived(DataMessageType::kControl, payload); }); + + // Sends another message and verifies it's unordered. + proxy->SendAsync(buffer, nullptr); + FlushNetworkThreadAndPendingOperations(); + EXPECT_FALSE(controller_->last_send_data_params().ordered); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedSendUnorderedAfterReceivesOpenAck) { + SetChannelReady(); + InternalDataChannelInit init; + init.id = 1; + init.ordered = false; + rtc::scoped_refptr dc = + controller_->CreateDataChannel("test1", init); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, dc->state(), 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); // Sends a message and verifies it's ordered. DataBuffer buffer("some data"); - ASSERT_TRUE(dc->Send(buffer)); + ASSERT_TRUE(proxy->Send(buffer)); EXPECT_TRUE(controller_->last_send_data_params().ordered); // Emulates receiving an OPEN_ACK message. rtc::CopyOnWriteBuffer payload; WriteDataChannelOpenAckMessage(&payload); - dc->OnDataReceived(DataMessageType::kControl, payload); + network_thread_.BlockingCall( + [&] { dc->OnDataReceived(DataMessageType::kControl, payload); }); // Sends another message and verifies it's unordered. - ASSERT_TRUE(dc->Send(buffer)); + ASSERT_TRUE(proxy->Send(buffer)); EXPECT_FALSE(controller_->last_send_data_params().ordered); } @@ -348,15 +582,40 @@ TEST_F(SctpDataChannelTest, SendUnorderedAfterReceiveData) { init.ordered = false; rtc::scoped_refptr dc = controller_->CreateDataChannel("test1", init); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, dc->state(), 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); // Emulates receiving a DATA message. DataBuffer buffer("data"); - dc->OnDataReceived(DataMessageType::kText, buffer.data); + network_thread_.BlockingCall( + [&] { dc->OnDataReceived(DataMessageType::kText, buffer.data); }); // Sends a message and verifies it's unordered. - ASSERT_TRUE(dc->Send(buffer)); + proxy->SendAsync(buffer, nullptr); + FlushNetworkThreadAndPendingOperations(); + EXPECT_FALSE(controller_->last_send_data_params().ordered); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedSendUnorderedAfterReceiveData) { + SetChannelReady(); + InternalDataChannelInit init; + init.id = 1; + init.ordered = false; + rtc::scoped_refptr dc = + controller_->CreateDataChannel("test1", init); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); + + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); + + // Emulates receiving a DATA message. + DataBuffer buffer("data"); + network_thread_.BlockingCall( + [&] { dc->OnDataReceived(DataMessageType::kText, buffer.data); }); + + // Sends a message and verifies it's unordered. + ASSERT_TRUE(proxy->Send(buffer)); EXPECT_FALSE(controller_->last_send_data_params().ordered); } @@ -367,10 +626,9 @@ TEST_F(SctpDataChannelTest, OpenWaitsForOpenMesssage) { controller_->set_send_blocked(true); SetChannelReady(); - EXPECT_EQ(DataChannelInterface::kConnecting, webrtc_data_channel_->state()); + EXPECT_EQ(DataChannelInterface::kConnecting, channel_->state()); controller_->set_send_blocked(false); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, webrtc_data_channel_->state(), - 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, channel_->state(), 1000); EXPECT_EQ(DataMessageType::kControl, controller_->last_send_data_params().type); } @@ -381,38 +639,67 @@ TEST_F(SctpDataChannelTest, QueuedCloseFlushes) { controller_->set_send_blocked(true); SetChannelReady(); - EXPECT_EQ(DataChannelInterface::kConnecting, webrtc_data_channel_->state()); + EXPECT_EQ(DataChannelInterface::kConnecting, channel_->state()); controller_->set_send_blocked(false); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, webrtc_data_channel_->state(), - 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, channel_->state(), 1000); controller_->set_send_blocked(true); - webrtc_data_channel_->Send(buffer); - webrtc_data_channel_->Close(); + channel_->SendAsync(buffer, nullptr); + channel_->Close(); controller_->set_send_blocked(false); - EXPECT_EQ_WAIT(DataChannelInterface::kClosed, webrtc_data_channel_->state(), - 1000); - EXPECT_TRUE(webrtc_data_channel_->error().ok()); + EXPECT_EQ_WAIT(DataChannelInterface::kClosed, channel_->state(), 1000); + EXPECT_TRUE(channel_->error().ok()); + EXPECT_EQ(DataMessageType::kText, controller_->last_send_data_params().type); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedQueuedCloseFlushes) { + DataBuffer buffer("foo"); + + controller_->set_send_blocked(true); + SetChannelReady(); + EXPECT_EQ(DataChannelInterface::kConnecting, channel_->state()); + controller_->set_send_blocked(false); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, channel_->state(), 1000); + controller_->set_send_blocked(true); + channel_->Send(buffer); + channel_->Close(); + controller_->set_send_blocked(false); + EXPECT_EQ_WAIT(DataChannelInterface::kClosed, channel_->state(), 1000); + EXPECT_TRUE(channel_->error().ok()); EXPECT_EQ(DataMessageType::kText, controller_->last_send_data_params().type); } // Tests that messages are sent with the right id. TEST_F(SctpDataChannelTest, SendDataId) { - webrtc_data_channel_->SetSctpSid(StreamId(1)); + SetChannelSid(inner_channel_, StreamId(1)); + SetChannelReady(); + DataBuffer buffer("data"); + channel_->SendAsync(buffer, nullptr); + FlushNetworkThreadAndPendingOperations(); + EXPECT_EQ(1, controller_->last_sid()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedSendDataId) { + SetChannelSid(inner_channel_, StreamId(1)); SetChannelReady(); DataBuffer buffer("data"); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + EXPECT_TRUE(channel_->Send(buffer)); EXPECT_EQ(1, controller_->last_sid()); } // Tests that the incoming messages with right ids are accepted. TEST_F(SctpDataChannelTest, ReceiveDataWithValidId) { - webrtc_data_channel_->SetSctpSid(StreamId(1)); + SetChannelSid(inner_channel_, StreamId(1)); SetChannelReady(); AddObserver(); DataBuffer buffer("abcd"); - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffer.data); + network_thread_.BlockingCall([&] { + inner_channel_->OnDataReceived(DataMessageType::kText, buffer.data); + }); + run_loop_.Flush(); EXPECT_EQ(1U, observer_->messages_received()); } @@ -427,8 +714,9 @@ TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) { SetChannelReady(); rtc::scoped_refptr dc = controller_->CreateDataChannel("test1", config); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, dc->state(), 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); EXPECT_EQ(0, controller_->last_sid()); } @@ -445,36 +733,39 @@ TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesReceived) { DataBuffer("message of the beast"), }); - webrtc_data_channel_->SetSctpSid(StreamId(1)); + SetChannelSid(inner_channel_, StreamId(1)); // Default values. - EXPECT_EQ(0U, webrtc_data_channel_->messages_received()); - EXPECT_EQ(0U, webrtc_data_channel_->bytes_received()); + EXPECT_EQ(0U, channel_->messages_received()); + EXPECT_EQ(0U, channel_->bytes_received()); // Receive three buffers while data channel isn't open. - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[0].data); - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[1].data); - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[2].data); + network_thread_.BlockingCall([&] { + for (int i : {0, 1, 2}) + inner_channel_->OnDataReceived(DataMessageType::kText, buffers[i].data); + }); EXPECT_EQ(0U, observer_->messages_received()); - EXPECT_EQ(0U, webrtc_data_channel_->messages_received()); - EXPECT_EQ(0U, webrtc_data_channel_->bytes_received()); + EXPECT_EQ(0U, channel_->messages_received()); + EXPECT_EQ(0U, channel_->bytes_received()); // Open channel and make sure everything was received. SetChannelReady(); size_t bytes_received = buffers[0].size() + buffers[1].size() + buffers[2].size(); EXPECT_EQ(3U, observer_->messages_received()); - EXPECT_EQ(3U, webrtc_data_channel_->messages_received()); - EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received()); + EXPECT_EQ(3U, channel_->messages_received()); + EXPECT_EQ(bytes_received, channel_->bytes_received()); // Receive three buffers while open. - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[3].data); - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[4].data); - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffers[5].data); + network_thread_.BlockingCall([&] { + for (int i : {3, 4, 5}) + inner_channel_->OnDataReceived(DataMessageType::kText, buffers[i].data); + }); + run_loop_.Flush(); bytes_received += buffers[3].size() + buffers[4].size() + buffers[5].size(); EXPECT_EQ(6U, observer_->messages_received()); - EXPECT_EQ(6U, webrtc_data_channel_->messages_received()); - EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received()); + EXPECT_EQ(6U, channel_->messages_received()); + EXPECT_EQ(bytes_received, channel_->bytes_received()); } // Tests that OPEN_ACK message is sent if the datachannel is created from an @@ -488,8 +779,9 @@ TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) { SetChannelReady(); rtc::scoped_refptr dc = controller_->CreateDataChannel("test1", config); + auto proxy = webrtc::SctpDataChannel::CreateProxy(dc, signaling_safety_); - EXPECT_EQ_WAIT(DataChannelInterface::kOpen, dc->state(), 1000); + EXPECT_EQ_WAIT(DataChannelInterface::kOpen, proxy->state(), 1000); EXPECT_EQ(config.id, controller_->last_sid()); EXPECT_EQ(DataMessageType::kControl, @@ -511,6 +803,36 @@ TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) { // Tests that that Send() returns false if the sending buffer is full // and the channel stays open. TEST_F(SctpDataChannelTest, OpenWhenSendBufferFull) { + AddObserver(); + SetChannelReady(); + + const size_t packetSize = 1024; + + rtc::CopyOnWriteBuffer buffer(packetSize); + memset(buffer.MutableData(), 0, buffer.size()); + + DataBuffer packet(buffer, true); + controller_->set_send_blocked(true); + size_t successful_send = 0u, failed_send = 0u; + auto send_complete = [&](RTCError err) { + err.ok() ? ++successful_send : ++failed_send; + }; + + size_t count = DataChannelInterface::MaxSendQueueSize() / packetSize; + for (size_t i = 0; i < count; ++i) { + channel_->SendAsync(packet, send_complete); + } + + // The sending buffer should be full, `Send()` returns false. + channel_->SendAsync(packet, std::move(send_complete)); + FlushNetworkThreadAndPendingOperations(); + EXPECT_TRUE(DataChannelInterface::kOpen == channel_->state()); + EXPECT_EQ(successful_send, count); + EXPECT_EQ(failed_send, 1u); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedOpenWhenSendBufferFull) { SetChannelReady(); const size_t packetSize = 1024; @@ -523,13 +845,12 @@ TEST_F(SctpDataChannelTest, OpenWhenSendBufferFull) { for (size_t i = 0; i < DataChannelInterface::MaxSendQueueSize() / packetSize; ++i) { - EXPECT_TRUE(webrtc_data_channel_->Send(packet)); + EXPECT_TRUE(channel_->Send(packet)); } - // The sending buffer shoul be full, send returns false. - EXPECT_FALSE(webrtc_data_channel_->Send(packet)); - - EXPECT_TRUE(DataChannelInterface::kOpen == webrtc_data_channel_->state()); + // The sending buffer should be full, `Send()` returns false. + EXPECT_FALSE(channel_->Send(packet)); + EXPECT_TRUE(DataChannelInterface::kOpen == channel_->state()); } // Tests that the DataChannel is closed on transport errors. @@ -538,13 +859,26 @@ TEST_F(SctpDataChannelTest, ClosedOnTransportError) { DataBuffer buffer("abcd"); controller_->set_transport_error(); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); + channel_->SendAsync(buffer, nullptr); - EXPECT_EQ(DataChannelInterface::kClosed, webrtc_data_channel_->state()); - EXPECT_FALSE(webrtc_data_channel_->error().ok()); - EXPECT_EQ(RTCErrorType::NETWORK_ERROR, webrtc_data_channel_->error().type()); - EXPECT_EQ(RTCErrorDetailType::NONE, - webrtc_data_channel_->error().error_detail()); + EXPECT_EQ(DataChannelInterface::kClosed, channel_->state()); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::NETWORK_ERROR, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::NONE, channel_->error().error_detail()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedClosedOnTransportError) { + SetChannelReady(); + DataBuffer buffer("abcd"); + controller_->set_transport_error(); + + EXPECT_TRUE(channel_->Send(buffer)); + + EXPECT_EQ(DataChannelInterface::kClosed, channel_->state()); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::NETWORK_ERROR, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::NONE, channel_->error().error_detail()); } // Tests that the DataChannel is closed if the received buffer is full. @@ -553,47 +887,87 @@ TEST_F(SctpDataChannelTest, ClosedWhenReceivedBufferFull) { rtc::CopyOnWriteBuffer buffer(1024); memset(buffer.MutableData(), 0, buffer.size()); - // Receiving data without having an observer will overflow the buffer. - for (size_t i = 0; i < 16 * 1024 + 1; ++i) { - webrtc_data_channel_->OnDataReceived(DataMessageType::kText, buffer); - } - EXPECT_EQ(DataChannelInterface::kClosed, webrtc_data_channel_->state()); - EXPECT_FALSE(webrtc_data_channel_->error().ok()); - EXPECT_EQ(RTCErrorType::RESOURCE_EXHAUSTED, - webrtc_data_channel_->error().type()); - EXPECT_EQ(RTCErrorDetailType::NONE, - webrtc_data_channel_->error().error_detail()); + network_thread_.BlockingCall([&] { + // Receiving data without having an observer will overflow the buffer. + for (size_t i = 0; i < 16 * 1024 + 1; ++i) { + inner_channel_->OnDataReceived(DataMessageType::kText, buffer); + } + }); + EXPECT_EQ(DataChannelInterface::kClosed, channel_->state()); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::RESOURCE_EXHAUSTED, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::NONE, channel_->error().error_detail()); } // Tests that sending empty data returns no error and keeps the channel open. TEST_F(SctpDataChannelTest, SendEmptyData) { - webrtc_data_channel_->SetSctpSid(StreamId(1)); + SetChannelSid(inner_channel_, StreamId(1)); + SetChannelReady(); + EXPECT_EQ(DataChannelInterface::kOpen, channel_->state()); + + DataBuffer buffer(""); + channel_->SendAsync(buffer, nullptr); + EXPECT_EQ(DataChannelInterface::kOpen, channel_->state()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedSendEmptyData) { + SetChannelSid(inner_channel_, StreamId(1)); SetChannelReady(); - EXPECT_EQ(DataChannelInterface::kOpen, webrtc_data_channel_->state()); + EXPECT_EQ(DataChannelInterface::kOpen, channel_->state()); DataBuffer buffer(""); - EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); - EXPECT_EQ(DataChannelInterface::kOpen, webrtc_data_channel_->state()); + EXPECT_TRUE(channel_->Send(buffer)); + EXPECT_EQ(DataChannelInterface::kOpen, channel_->state()); } // Tests that a channel can be closed without being opened or assigned an sid. TEST_F(SctpDataChannelTest, NeverOpened) { controller_->set_transport_available(true); - webrtc_data_channel_->OnTransportChannelCreated(); - webrtc_data_channel_->Close(); + network_thread_.BlockingCall( + [&] { inner_channel_->OnTransportChannelCreated(); }); + channel_->Close(); } // Tests that a data channel that's not connected to a transport can transition // directly to the `kClosed` state when closed. // See also chromium:1421534. TEST_F(SctpDataChannelTest, UnusedTransitionsDirectlyToClosed) { - webrtc_data_channel_->Close(); - EXPECT_EQ(DataChannelInterface::kClosed, webrtc_data_channel_->state()); + channel_->Close(); + EXPECT_EQ(DataChannelInterface::kClosed, channel_->state()); } // Test that the data channel goes to the "closed" state (and doesn't crash) // when its transport goes away, even while data is buffered. TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) { + AddObserver(); + SetChannelReady(); + + rtc::CopyOnWriteBuffer buffer(1024); + memset(buffer.MutableData(), 0, buffer.size()); + DataBuffer packet(buffer, true); + + // Send a packet while sending is blocked so it ends up buffered. + controller_->set_send_blocked(true); + channel_->SendAsync(packet, nullptr); + + // Tell the data channel that its transport is being destroyed. + // It should then stop using the transport (allowing us to delete it) and + // transition to the "closed" state. + RTCError error(RTCErrorType::OPERATION_ERROR_WITH_DATA, ""); + error.set_error_detail(RTCErrorDetailType::SCTP_FAILURE); + network_thread_.BlockingCall( + [&] { inner_channel_->OnTransportChannelClosed(error); }); + controller_.reset(nullptr); + EXPECT_EQ_WAIT(DataChannelInterface::kClosed, channel_->state(), + kDefaultTimeout); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::OPERATION_ERROR_WITH_DATA, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::SCTP_FAILURE, channel_->error().error_detail()); +} + +// TODO(tommi): This test uses `Send()`. Remove once fully deprecated. +TEST_F(SctpDataChannelTest, DeprecatedTransportDestroyedWhileDataBuffered) { SetChannelReady(); rtc::CopyOnWriteBuffer buffer(1024); @@ -602,22 +976,21 @@ TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) { // Send a packet while sending is blocked so it ends up buffered. controller_->set_send_blocked(true); - EXPECT_TRUE(webrtc_data_channel_->Send(packet)); + EXPECT_TRUE(channel_->Send(packet)); // Tell the data channel that its transport is being destroyed. // It should then stop using the transport (allowing us to delete it) and // transition to the "closed" state. RTCError error(RTCErrorType::OPERATION_ERROR_WITH_DATA, ""); error.set_error_detail(RTCErrorDetailType::SCTP_FAILURE); - webrtc_data_channel_->OnTransportChannelClosed(error); + network_thread_.BlockingCall( + [&] { inner_channel_->OnTransportChannelClosed(error); }); controller_.reset(nullptr); - EXPECT_EQ_WAIT(DataChannelInterface::kClosed, webrtc_data_channel_->state(), + EXPECT_EQ_WAIT(DataChannelInterface::kClosed, channel_->state(), kDefaultTimeout); - EXPECT_FALSE(webrtc_data_channel_->error().ok()); - EXPECT_EQ(RTCErrorType::OPERATION_ERROR_WITH_DATA, - webrtc_data_channel_->error().type()); - EXPECT_EQ(RTCErrorDetailType::SCTP_FAILURE, - webrtc_data_channel_->error().error_detail()); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::OPERATION_ERROR_WITH_DATA, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::SCTP_FAILURE, channel_->error().error_detail()); } TEST_F(SctpDataChannelTest, TransportGotErrorCode) { @@ -631,18 +1004,17 @@ TEST_F(SctpDataChannelTest, TransportGotErrorCode) { error.set_error_detail(RTCErrorDetailType::SCTP_FAILURE); error.set_sctp_cause_code( static_cast(cricket::SctpErrorCauseCode::kProtocolViolation)); - webrtc_data_channel_->OnTransportChannelClosed(error); + network_thread_.BlockingCall( + [&] { inner_channel_->OnTransportChannelClosed(error); }); controller_.reset(nullptr); - EXPECT_EQ_WAIT(DataChannelInterface::kClosed, webrtc_data_channel_->state(), + EXPECT_EQ_WAIT(DataChannelInterface::kClosed, channel_->state(), kDefaultTimeout); - EXPECT_FALSE(webrtc_data_channel_->error().ok()); - EXPECT_EQ(RTCErrorType::OPERATION_ERROR_WITH_DATA, - webrtc_data_channel_->error().type()); - EXPECT_EQ(RTCErrorDetailType::SCTP_FAILURE, - webrtc_data_channel_->error().error_detail()); + EXPECT_FALSE(channel_->error().ok()); + EXPECT_EQ(RTCErrorType::OPERATION_ERROR_WITH_DATA, channel_->error().type()); + EXPECT_EQ(RTCErrorDetailType::SCTP_FAILURE, channel_->error().error_detail()); EXPECT_EQ( static_cast(cricket::SctpErrorCauseCode::kProtocolViolation), - webrtc_data_channel_->error().sctp_cause_code()); + channel_->error().sctp_cause_code()); } class SctpSidAllocatorTest : public ::testing::Test { @@ -712,5 +1084,69 @@ TEST_F(SctpSidAllocatorTest, SctpIdReusedForRemovedDataChannel) { EXPECT_EQ(even_id.stream_id_int() + 6, allocated_id.stream_id_int()); } +// Code coverage tests for default implementations in data_channel_interface.*. +namespace { +class NoImplDataChannel : public DataChannelInterface { + public: + NoImplDataChannel() = default; + // Send and SendAsync implementations are public and implementation + // is in data_channel_interface.cc. + + private: + // Implementation for pure virtual methods, just for compilation sake. + void RegisterObserver(DataChannelObserver* observer) override {} + void UnregisterObserver() override {} + std::string label() const override { return ""; } + bool reliable() const override { return false; } + int id() const override { return -1; } + DataState state() const override { return DataChannelInterface::kClosed; } + uint32_t messages_sent() const override { return 0u; } + uint64_t bytes_sent() const override { return 0u; } + uint32_t messages_received() const override { return 0u; } + uint64_t bytes_received() const override { return 0u; } + uint64_t buffered_amount() const override { return 0u; } + void Close() override {} +}; + +class NoImplObserver : public DataChannelObserver { + public: + NoImplObserver() = default; + + private: + void OnStateChange() override {} + void OnMessage(const DataBuffer& buffer) override {} +}; +} // namespace + +TEST(DataChannelInterfaceTest, Coverage) { + auto channel = rtc::make_ref_counted(); + EXPECT_FALSE(channel->ordered()); + EXPECT_EQ(channel->maxRetransmitTime(), 0u); + EXPECT_EQ(channel->maxRetransmits(), 0u); + EXPECT_FALSE(channel->maxRetransmitsOpt()); + EXPECT_FALSE(channel->maxPacketLifeTime()); + EXPECT_TRUE(channel->protocol().empty()); + EXPECT_FALSE(channel->negotiated()); + EXPECT_EQ(channel->MaxSendQueueSize(), 16u * 1024u * 1024u); + + NoImplObserver observer; + observer.OnBufferedAmountChange(0u); + EXPECT_FALSE(observer.IsOkToCallOnTheNetworkThread()); +} + +#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) + +TEST(DataChannelInterfaceDeathTest, SendDefaultImplDchecks) { + auto channel = rtc::make_ref_counted(); + RTC_EXPECT_DEATH(channel->Send(DataBuffer("Foo")), "Check failed: false"); +} + +TEST(DataChannelInterfaceDeathTest, SendAsyncDefaultImplDchecks) { + auto channel = rtc::make_ref_counted(); + RTC_EXPECT_DEATH(channel->SendAsync(DataBuffer("Foo"), nullptr), + "Check failed: false"); +} +#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/pc/ice_server_parsing.cc b/third_party/libwebrtc/pc/ice_server_parsing.cc index 9322fd12d4f24..896305c54b003 100644 --- a/third_party/libwebrtc/pc/ice_server_parsing.cc +++ b/third_party/libwebrtc/pc/ice_server_parsing.cc @@ -220,6 +220,15 @@ RTCError ParseIceServerUrl( // GetServiceTypeAndHostnameFromUri should never give an empty hoststring RTC_DCHECK(!hoststring.empty()); + // stun with ?transport (or any ?) is not valid. + if ((service_type == ServiceType::STUN || + service_type == ServiceType::STUNS) && + tokens.size() > 1) { + LOG_AND_RETURN_ERROR( + RTCErrorType::SYNTAX_ERROR, + "ICE server parsing failed: Invalid stun url with query parameters"); + } + int default_port = kDefaultStunPort; if (service_type == ServiceType::TURNS) { default_port = kDefaultStunTlsPort; diff --git a/third_party/libwebrtc/pc/ice_server_parsing_unittest.cc b/third_party/libwebrtc/pc/ice_server_parsing_unittest.cc index 4cb7c47b0ba13..4356b1efb0ba4 100644 --- a/third_party/libwebrtc/pc/ice_server_parsing_unittest.cc +++ b/third_party/libwebrtc/pc/ice_server_parsing_unittest.cc @@ -188,6 +188,8 @@ TEST_F(IceServerParsingTest, ParseHostnameAndPort) { EXPECT_FALSE(ParseUrl("stun:/hostname")); // / is not allowed EXPECT_FALSE(ParseUrl("stun:?hostname")); // ? is not allowed EXPECT_FALSE(ParseUrl("stun:#hostname")); // # is not allowed + // STUN explicitly forbids query parameters. + EXPECT_FALSE(ParseUrl("stun:hostname?transport=udp")); } // Test parsing the "?transport=xxx" part of the URL. diff --git a/third_party/libwebrtc/pc/jitter_buffer_delay.cc b/third_party/libwebrtc/pc/jitter_buffer_delay.cc index 801cef721568f..f22b0650f9a98 100644 --- a/third_party/libwebrtc/pc/jitter_buffer_delay.cc +++ b/third_party/libwebrtc/pc/jitter_buffer_delay.cc @@ -22,10 +22,6 @@ constexpr int kMaximumDelayMs = 10000; namespace webrtc { -JitterBufferDelay::JitterBufferDelay() { - worker_thread_checker_.Detach(); -} - void JitterBufferDelay::Set(absl::optional delay_seconds) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); cached_delay_seconds_ = delay_seconds; diff --git a/third_party/libwebrtc/pc/jitter_buffer_delay.h b/third_party/libwebrtc/pc/jitter_buffer_delay.h index a6bec01ce764d..caf713b045f67 100644 --- a/third_party/libwebrtc/pc/jitter_buffer_delay.h +++ b/third_party/libwebrtc/pc/jitter_buffer_delay.h @@ -25,13 +25,14 @@ namespace webrtc { // the start of media_channel by caching its request. class JitterBufferDelay { public: - JitterBufferDelay(); + JitterBufferDelay() = default; void Set(absl::optional delay_seconds); int GetMs() const; private: - RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_{ + SequenceChecker::kDetached}; absl::optional cached_delay_seconds_ RTC_GUARDED_BY(&worker_thread_checker_); }; diff --git a/third_party/libwebrtc/pc/jsep_transport_collection.h b/third_party/libwebrtc/pc/jsep_transport_collection.h index 0bb19a3260307..f5eba64e96f9d 100644 --- a/third_party/libwebrtc/pc/jsep_transport_collection.h +++ b/third_party/libwebrtc/pc/jsep_transport_collection.h @@ -44,10 +44,7 @@ namespace webrtc { class BundleManager { public: explicit BundleManager(PeerConnectionInterface::BundlePolicy bundle_policy) - : bundle_policy_(bundle_policy) { - // Allow constructor to be called on a different thread. - sequence_checker_.Detach(); - } + : bundle_policy_(bundle_policy) {} const std::vector>& bundle_groups() const { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -76,7 +73,8 @@ class BundleManager { // Recalculate established_bundle_groups_by_mid_ from bundle_groups_. void RefreshEstablishedBundleGroupsByMid() RTC_RUN_ON(sequence_checker_); - RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ + SequenceChecker::kDetached}; PeerConnectionInterface::BundlePolicy bundle_policy_; std::vector> bundle_groups_ RTC_GUARDED_BY(sequence_checker_); @@ -97,10 +95,7 @@ class JsepTransportCollection { map_change_callback, std::function state_change_callback) : map_change_callback_(map_change_callback), - state_change_callback_(state_change_callback) { - // Allow constructor to be called on a different thread. - sequence_checker_.Detach(); - } + state_change_callback_(state_change_callback) {} void RegisterTransport(const std::string& mid, std::unique_ptr transport); @@ -151,7 +146,8 @@ class JsepTransportCollection { bool IsConsistent(); // For testing only: Verify internal structure. - RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ + SequenceChecker::kDetached}; // This member owns the JSEP transports. std::map> jsep_transports_by_name_ RTC_GUARDED_BY(sequence_checker_); diff --git a/third_party/libwebrtc/pc/jsep_transport_controller.cc b/third_party/libwebrtc/pc/jsep_transport_controller.cc index 3ea24d4503d86..4c351a69ef981 100644 --- a/third_party/libwebrtc/pc/jsep_transport_controller.cc +++ b/third_party/libwebrtc/pc/jsep_transport_controller.cc @@ -53,7 +53,7 @@ JsepTransportController::JsepTransportController( RTC_DCHECK_RUN_ON(network_thread_); UpdateAggregateStates_n(); }), - config_(config), + config_(std::move(config)), active_reset_srtp_params_(config.active_reset_srtp_params), bundles_(config.bundle_policy) { // The `transport_observer` is assumed to be non-null. @@ -1090,6 +1090,8 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( jsep_transport->rtp_transport()->SignalRtcpPacketReceived.connect( this, &JsepTransportController::OnRtcpPacketReceived_n); + jsep_transport->rtp_transport()->SignalUnDemuxableRtpPacketReceived.connect( + this, &JsepTransportController::OnUnDemuxableRtpPacketReceived_n); transports_.RegisterTransport(content_info.name, std::move(jsep_transport)); UpdateAggregateStates_n(); @@ -1410,6 +1412,12 @@ void JsepTransportController::OnRtcpPacketReceived_n( config_.rtcp_handler(*packet, packet_time_us); } +void JsepTransportController::OnUnDemuxableRtpPacketReceived_n( + const webrtc::RtpPacketReceived& packet) { + RTC_DCHECK(config_.un_demuxable_packet_handler); + config_.un_demuxable_packet_handler(packet); +} + void JsepTransportController::OnDtlsHandshakeError( rtc::SSLHandshakeError error) { config_.on_dtls_handshake_error_(error); diff --git a/third_party/libwebrtc/pc/jsep_transport_controller.h b/third_party/libwebrtc/pc/jsep_transport_controller.h index 4779bf9227937..5880e346cdd4a 100644 --- a/third_party/libwebrtc/pc/jsep_transport_controller.h +++ b/third_party/libwebrtc/pc/jsep_transport_controller.h @@ -21,6 +21,7 @@ #include #include +#include "absl/functional/any_invocable.h" #include "absl/types/optional.h" #include "api/async_dns_resolver.h" #include "api/candidate.h" @@ -124,9 +125,11 @@ class JsepTransportController : public sigslot::has_slots<> { Observer* transport_observer = nullptr; // Must be provided and valid for the lifetime of the // JsepTransportController instance. - std::function + absl::AnyInvocable rtcp_handler; + absl::AnyInvocable + un_demuxable_packet_handler; // Initial value for whether DtlsTransport reset causes a reset // of SRTP parameters. bool active_reset_srtp_params = false; @@ -450,6 +453,8 @@ class JsepTransportController : public sigslot::has_slots<> { void OnRtcpPacketReceived_n(rtc::CopyOnWriteBuffer* packet, int64_t packet_time_us) RTC_RUN_ON(network_thread_); + void OnUnDemuxableRtpPacketReceived_n(const webrtc::RtpPacketReceived& packet) + RTC_RUN_ON(network_thread_); void OnDtlsHandshakeError(rtc::SSLHandshakeError error); diff --git a/third_party/libwebrtc/pc/jsep_transport_controller_unittest.cc b/third_party/libwebrtc/pc/jsep_transport_controller_unittest.cc index c30f3819710a0..3c3018dab1113 100644 --- a/third_party/libwebrtc/pc/jsep_transport_controller_unittest.cc +++ b/third_party/libwebrtc/pc/jsep_transport_controller_unittest.cc @@ -103,7 +103,7 @@ class JsepTransportControllerTest : public JsepTransportController::Observer, config.field_trials = &field_trials_; transport_controller_ = std::make_unique( network_thread, port_allocator, nullptr /* async_resolver_factory */, - config); + std::move(config)); SendTask(network_thread, [&] { ConnectTransportControllerSignals(); }); } @@ -400,7 +400,7 @@ TEST_F(JsepTransportControllerTest, GetRtpTransport) { TEST_F(JsepTransportControllerTest, GetDtlsTransport) { JsepTransportController::Config config; config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyNegotiate; - CreateJsepTransportController(config); + CreateJsepTransportController(std::move(config)); auto description = CreateSessionDescriptionWithoutBundle(); EXPECT_TRUE(transport_controller_ ->SetLocalDescription(SdpType::kOffer, description.get()) @@ -435,7 +435,7 @@ TEST_F(JsepTransportControllerTest, GetDtlsTransport) { TEST_F(JsepTransportControllerTest, GetDtlsTransportWithRtcpMux) { JsepTransportController::Config config; config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; - CreateJsepTransportController(config); + CreateJsepTransportController(std::move(config)); auto description = CreateSessionDescriptionWithoutBundle(); EXPECT_TRUE(transport_controller_ ->SetLocalDescription(SdpType::kOffer, description.get()) @@ -987,7 +987,7 @@ TEST_F(JsepTransportControllerTest, IceRoleNotRedetermined) { JsepTransportController::Config config; config.redetermine_role_on_ice_restart = false; - CreateJsepTransportController(config); + CreateJsepTransportController(std::move(config)); // Let the `transport_controller_` be the controlled side initially. auto remote_offer = std::make_unique(); AddAudioSection(remote_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, @@ -2317,7 +2317,7 @@ TEST_F(JsepTransportControllerTest, RejectFirstContentInBundleGroup) { TEST_F(JsepTransportControllerTest, ApplyNonRtcpMuxOfferWhenMuxingRequired) { JsepTransportController::Config config; config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; - CreateJsepTransportController(config); + CreateJsepTransportController(std::move(config)); auto local_offer = std::make_unique(); AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_ACTPASS, @@ -2335,7 +2335,7 @@ TEST_F(JsepTransportControllerTest, ApplyNonRtcpMuxOfferWhenMuxingRequired) { TEST_F(JsepTransportControllerTest, ApplyNonRtcpMuxAnswerWhenMuxingRequired) { JsepTransportController::Config config; config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; - CreateJsepTransportController(config); + CreateJsepTransportController(std::move(config)); auto local_offer = std::make_unique(); AddAudioSection(local_offer.get(), kAudioMid1, kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_ACTPASS, diff --git a/third_party/libwebrtc/pc/legacy_stats_collector.cc b/third_party/libwebrtc/pc/legacy_stats_collector.cc index 6829e359b8cea..6533fc30680d5 100644 --- a/third_party/libwebrtc/pc/legacy_stats_collector.cc +++ b/third_party/libwebrtc/pc/legacy_stats_collector.cc @@ -34,7 +34,6 @@ #include "api/video/video_timing.h" #include "call/call.h" #include "media/base/media_channel.h" -#include "media/base/media_channel_impl.h" #include "modules/audio_processing/include/audio_processing_statistics.h" #include "p2p/base/ice_transport_internal.h" #include "p2p/base/p2p_constants.h" @@ -207,7 +206,7 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, {StatsReport::kStatsValueNameJitterBufferMs, info.jitter_buffer_ms}, {StatsReport::kStatsValueNameJitterReceived, info.jitter_ms}, {StatsReport::kStatsValueNamePacketsLost, info.packets_lost}, - {StatsReport::kStatsValueNamePacketsReceived, info.packets_rcvd}, + {StatsReport::kStatsValueNamePacketsReceived, info.packets_received}, {StatsReport::kStatsValueNamePreferredJitterBufferMs, info.jitter_buffer_preferred_ms}, }; @@ -225,11 +224,11 @@ void ExtractStats(const cricket::VoiceReceiverInfo& info, report->AddInt(StatsReport::kStatsValueNameDecodingCodecPLC, info.decoding_codec_plc); - int64_t bytes_rcvd = info.payload_bytes_rcvd; + int64_t bytes_received = info.payload_bytes_received; if (!use_standard_bytes_stats) { - bytes_rcvd += info.header_and_padding_bytes_rcvd; + bytes_received += info.header_and_padding_bytes_received; } - report->AddInt64(StatsReport::kStatsValueNameBytesReceived, bytes_rcvd); + report->AddInt64(StatsReport::kStatsValueNameBytesReceived, bytes_received); if (info.capture_start_ntp_time_ms >= 0) { report->AddInt64(StatsReport::kStatsValueNameCaptureStartNtpTimeMs, info.capture_start_ntp_time_ms); @@ -303,11 +302,11 @@ void ExtractStats(const cricket::VideoReceiverInfo& info, ExtractCommonReceiveProperties(info, report); report->AddString(StatsReport::kStatsValueNameCodecImplementationName, info.decoder_implementation_name); - int64_t bytes_rcvd = info.payload_bytes_rcvd; + int64_t bytes_received = info.payload_bytes_received; if (!use_standard_bytes_stats) { - bytes_rcvd += info.header_and_padding_bytes_rcvd; + bytes_received += info.header_and_padding_bytes_received; } - report->AddInt64(StatsReport::kStatsValueNameBytesReceived, bytes_rcvd); + report->AddInt64(StatsReport::kStatsValueNameBytesReceived, bytes_received); if (info.capture_start_ntp_time_ms >= 0) { report->AddInt64(StatsReport::kStatsValueNameCaptureStartNtpTimeMs, info.capture_start_ntp_time_ms); @@ -330,14 +329,14 @@ void ExtractStats(const cricket::VideoReceiverInfo& info, {StatsReport::kStatsValueNameFrameHeightReceived, info.frame_height}, {StatsReport::kStatsValueNameFrameRateDecoded, info.framerate_decoded}, {StatsReport::kStatsValueNameFrameRateOutput, info.framerate_output}, - {StatsReport::kStatsValueNameFrameRateReceived, info.framerate_rcvd}, + {StatsReport::kStatsValueNameFrameRateReceived, info.framerate_received}, {StatsReport::kStatsValueNameFrameWidthReceived, info.frame_width}, {StatsReport::kStatsValueNameJitterBufferMs, info.jitter_buffer_ms}, {StatsReport::kStatsValueNameMaxDecodeMs, info.max_decode_ms}, {StatsReport::kStatsValueNameMinPlayoutDelayMs, info.min_playout_delay_ms}, {StatsReport::kStatsValueNamePacketsLost, info.packets_lost}, - {StatsReport::kStatsValueNamePacketsReceived, info.packets_rcvd}, + {StatsReport::kStatsValueNamePacketsReceived, info.packets_received}, {StatsReport::kStatsValueNamePlisSent, info.plis_sent}, {StatsReport::kStatsValueNameRenderDelayMs, info.render_delay_ms}, {StatsReport::kStatsValueNameTargetDelayMs, info.target_delay_ms}, @@ -383,15 +382,15 @@ void ExtractStats(const cricket::VideoSenderInfo& info, {StatsReport::kStatsValueNameAvgEncodeMs, info.avg_encode_ms}, {StatsReport::kStatsValueNameEncodeUsagePercent, info.encode_usage_percent}, - {StatsReport::kStatsValueNameFirsReceived, info.firs_rcvd}, + {StatsReport::kStatsValueNameFirsReceived, info.firs_received}, {StatsReport::kStatsValueNameFrameHeightSent, info.send_frame_height}, {StatsReport::kStatsValueNameFrameRateInput, round(info.framerate_input)}, {StatsReport::kStatsValueNameFrameRateSent, info.framerate_sent}, {StatsReport::kStatsValueNameFrameWidthSent, info.send_frame_width}, - {StatsReport::kStatsValueNameNacksReceived, info.nacks_rcvd}, + {StatsReport::kStatsValueNameNacksReceived, info.nacks_received}, {StatsReport::kStatsValueNamePacketsLost, info.packets_lost}, {StatsReport::kStatsValueNamePacketsSent, info.packets_sent}, - {StatsReport::kStatsValueNamePlisReceived, info.plis_rcvd}, + {StatsReport::kStatsValueNamePlisReceived, info.plis_received}, {StatsReport::kStatsValueNameFramesEncoded, info.frames_encoded}, {StatsReport::kStatsValueNameHugeFramesSent, info.huge_frames_sent}, }; @@ -670,7 +669,7 @@ void LegacyStatsCollector::UpdateStats( // to fetch stats, then applies them on the signaling thread. See if we need // to do this synchronously or if updating the stats without blocking is safe. std::map transport_names_by_mid = - ExtractSessionInfo(); + ExtractSessionAndDataInfo(); // TODO(tommi): All of these hop over to the worker thread to fetch // information. We could post a task to run all of these and post @@ -681,7 +680,6 @@ void LegacyStatsCollector::UpdateStats( ExtractBweInfo(); ExtractMediaInfo(transport_names_by_mid); ExtractSenderInfo(); - ExtractDataInfo(); UpdateTrackReports(); } @@ -856,19 +854,26 @@ StatsReport* LegacyStatsCollector::AddCandidateReport( return report; } -std::map LegacyStatsCollector::ExtractSessionInfo() { - TRACE_EVENT0("webrtc", "LegacyStatsCollector::ExtractSessionInfo"); +std::map +LegacyStatsCollector::ExtractSessionAndDataInfo() { + TRACE_EVENT0("webrtc", "LegacyStatsCollector::ExtractSessionAndDataInfo"); RTC_DCHECK_RUN_ON(pc_->signaling_thread()); SessionStats stats; + StatsCollection::Container data_report_collection; auto transceivers = pc_->GetTransceiversInternal(); pc_->network_thread()->BlockingCall( [&, sctp_transport_name = pc_->sctp_transport_name(), sctp_mid = pc_->sctp_mid()]() mutable { stats = ExtractSessionInfo_n( transceivers, std::move(sctp_transport_name), std::move(sctp_mid)); + StatsCollection data_reports; + ExtractDataInfo_n(&data_reports); + data_report_collection = data_reports.DetachCollection(); }); + reports_.MergeCollection(std::move(data_report_collection)); + ExtractSessionInfo_s(stats); return std::move(stats.transport_names_by_mid); @@ -1292,8 +1297,8 @@ void LegacyStatsCollector::ExtractSenderInfo() { } } -void LegacyStatsCollector::ExtractDataInfo() { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); +void LegacyStatsCollector::ExtractDataInfo_n(StatsCollection* reports) { + RTC_DCHECK_RUN_ON(pc_->network_thread()); rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; @@ -1301,7 +1306,7 @@ void LegacyStatsCollector::ExtractDataInfo() { for (const auto& stats : data_stats) { StatsReport::Id id(StatsReport::NewTypedIntId( StatsReport::kStatsReportTypeDataChannel, stats.id)); - StatsReport* report = reports_.ReplaceOrAddNew(id); + StatsReport* report = reports->ReplaceOrAddNew(id); report->set_timestamp(stats_gathering_started_); report->AddString(StatsReport::kStatsValueNameLabel, stats.label); // Filter out the initial id (-1). diff --git a/third_party/libwebrtc/pc/legacy_stats_collector.h b/third_party/libwebrtc/pc/legacy_stats_collector.h index cedd36c8537b8..e905b39d486b9 100644 --- a/third_party/libwebrtc/pc/legacy_stats_collector.h +++ b/third_party/libwebrtc/pc/legacy_stats_collector.h @@ -165,11 +165,13 @@ class LegacyStatsCollector : public LegacyStatsCollectorInterface { const StatsReport::Id& channel_report_id, const cricket::ConnectionInfo& info); - void ExtractDataInfo(); + void ExtractDataInfo_n(StatsCollection* reports); // Returns the `transport_names_by_mid` member from the SessionStats as - // gathered and used to populate the stats. - std::map ExtractSessionInfo(); + // gathered and used to populate the stats. Contains one synchronous hop + // to the network thread to get this information along with querying data + // channel stats at the same time and populating `reports_`. + std::map ExtractSessionAndDataInfo(); void ExtractBweInfo(); void ExtractMediaInfo( diff --git a/third_party/libwebrtc/pc/legacy_stats_collector_unittest.cc b/third_party/libwebrtc/pc/legacy_stats_collector_unittest.cc index 6d3fd9f4623b4..3099d1188a736 100644 --- a/third_party/libwebrtc/pc/legacy_stats_collector_unittest.cc +++ b/third_party/libwebrtc/pc/legacy_stats_collector_unittest.cc @@ -40,6 +40,7 @@ #include "rtc_base/fake_ssl_identity.h" #include "rtc_base/message_digest.h" #include "rtc_base/net_helper.h" +#include "rtc_base/null_socket_server.h" #include "rtc_base/rtc_certificate.h" #include "rtc_base/socket_address.h" #include "rtc_base/ssl_identity.h" @@ -328,8 +329,8 @@ void VerifyVoiceReceiverInfoReport(const StatsReport* report, EXPECT_EQ(rtc::ToString(info.audio_level), value_in_report); EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameBytesReceived, &value_in_report)); - EXPECT_EQ(rtc::ToString(info.payload_bytes_rcvd + - info.header_and_padding_bytes_rcvd), + EXPECT_EQ(rtc::ToString(info.payload_bytes_received + + info.header_and_padding_bytes_received), value_in_report); EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameJitterReceived, &value_in_report)); @@ -365,7 +366,7 @@ void VerifyVoiceReceiverInfoReport(const StatsReport* report, EXPECT_EQ(rtc::ToString(info.secondary_discarded_rate), value_in_report); EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNamePacketsReceived, &value_in_report)); - EXPECT_EQ(rtc::ToString(info.packets_rcvd), value_in_report); + EXPECT_EQ(rtc::ToString(info.packets_received), value_in_report); EXPECT_TRUE(GetValue(report, StatsReport::kStatsValueNameDecodingCTSG, &value_in_report)); EXPECT_EQ(rtc::ToString(info.decoding_calls_to_silence_generator), @@ -565,9 +566,9 @@ void UpdateVoiceSenderInfoFromAudioTrack( void InitVoiceReceiverInfo(cricket::VoiceReceiverInfo* voice_receiver_info) { voice_receiver_info->add_ssrc(kSsrcOfTrack); - voice_receiver_info->payload_bytes_rcvd = 98; - voice_receiver_info->header_and_padding_bytes_rcvd = 12; - voice_receiver_info->packets_rcvd = 111; + voice_receiver_info->payload_bytes_received = 98; + voice_receiver_info->header_and_padding_bytes_received = 12; + voice_receiver_info->packets_received = 111; voice_receiver_info->packets_lost = 114; voice_receiver_info->jitter_ms = 116; voice_receiver_info->jitter_buffer_ms = 117; @@ -846,6 +847,58 @@ class StatsCollectorTrackTest : public LegacyStatsCollectorTest, rtc::scoped_refptr audio_track_; }; +TEST(StatsCollectionTest, DetachAndMerge) { + StatsCollection collection; + ASSERT_EQ(collection.size(), 0u); + + // Create a new report with some information. + StatsReport::Id id( + StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack, "track_id")); + StatsReport* report = collection.ReplaceOrAddNew(id); + report->AddString(StatsReport::kStatsValueNameTrackId, "track_id"); + ASSERT_TRUE(report); + // Check that looking it up, yields the same report. + ASSERT_EQ(report, collection.FindOrAddNew(id)); + // There should be one report now. + ASSERT_EQ(collection.size(), 1u); + + // Detach the internal container from the StatsCollection. + StatsCollection::Container container = collection.DetachCollection(); + EXPECT_EQ(container.size(), 1u); + EXPECT_EQ(collection.size(), 0u); + EXPECT_EQ(nullptr, collection.Find(id)); + + // Merge it back and test if we find the same report. + collection.MergeCollection(std::move(container)); + EXPECT_EQ(collection.size(), 1u); + EXPECT_EQ(report, collection.Find(id)); +} + +// Similar to `DetachAndMerge` above but detaches on one thread, merges on +// another to test that we don't trigger sequence checker. +TEST(StatsCollectionTest, DetachAndMergeThreaded) { + rtc::Thread new_thread(std::make_unique()); + new_thread.Start(); + + StatsReport::Id id( + StatsReport::NewTypedId(StatsReport::kStatsReportTypeTrack, "track_id")); + + StatsReport* expected_report = nullptr; + + StatsCollection::Container container = new_thread.BlockingCall([&] { + StatsCollection collection; + expected_report = collection.ReplaceOrAddNew(id); + expected_report->AddString(StatsReport::kStatsValueNameTrackId, "track_id"); + return collection.DetachCollection(); + }); + + StatsCollection collection; + collection.MergeCollection(std::move(container)); + EXPECT_EQ(collection.size(), 1u); + EXPECT_EQ(expected_report, collection.Find(id)); + + new_thread.Stop(); +} TEST_F(LegacyStatsCollectorTest, FilterOutNegativeDataChannelId) { auto pc = CreatePeerConnection(); auto stats = CreateStatsCollector(pc.get()); diff --git a/third_party/libwebrtc/pc/media_session.cc b/third_party/libwebrtc/pc/media_session.cc index e703b44101edd..274d7ce8b2b8e 100644 --- a/third_party/libwebrtc/pc/media_session.cc +++ b/third_party/libwebrtc/pc/media_session.cc @@ -685,7 +685,9 @@ static bool CreateContentOffer( // TODO(crbug.com/1051821): Configure the extension direction from // the information in the media_description_options extension // capability. - extensions.push_back(extension_with_id); + if (extension.direction != RtpTransceiverDirection::kStopped) { + extensions.push_back(extension_with_id); + } } } } @@ -946,8 +948,10 @@ static const C* GetAssociatedCodecForRed(const std::vector& codec_list, std::string fmtp; if (!red_codec.GetParam(kCodecParamNotInNameValueFormat, &fmtp)) { // Normal for video/RED. - RTC_LOG(LS_WARNING) << "RED codec " << red_codec.name - << " is missing an associated payload type."; + if constexpr (std::is_same_v) { + RTC_LOG(LS_WARNING) << "RED codec " << red_codec.name + << " is missing an associated payload type."; + } return nullptr; } @@ -1409,8 +1413,24 @@ static bool CreateMediaContentAnswer( enable_encrypted_rtp_header_extensions ? webrtc::RtpExtension::Filter::kPreferEncryptedExtension : webrtc::RtpExtension::Filter::kDiscardEncryptedExtension; + + // Filter local extensions by capabilities and direction. + RtpHeaderExtensions local_rtp_extensions_to_reply_with; + for (auto extension_with_id : local_rtp_extensions) { + for (const auto& extension : media_description_options.header_extensions) { + if (extension_with_id.uri == extension.uri) { + // TODO(crbug.com/1051821): Configure the extension direction from + // the information in the media_description_options extension + // capability. For now, do not include stopped extensions. + // See also crbug.com/webrtc/7477 about the general lack of direction. + if (extension.direction != RtpTransceiverDirection::kStopped) { + local_rtp_extensions_to_reply_with.push_back(extension_with_id); + } + } + } + } RtpHeaderExtensions negotiated_rtp_extensions; - NegotiateRtpHeaderExtensions(local_rtp_extensions, + NegotiateRtpHeaderExtensions(local_rtp_extensions_to_reply_with, offer->rtp_header_extensions(), extensions_filter, &negotiated_rtp_extensions); answer->set_rtp_header_extensions(negotiated_rtp_extensions); @@ -2589,7 +2609,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( const SessionDescription* current_description, const TransportInfo* bundle_transport, const AudioCodecs& audio_codecs, - const RtpHeaderExtensions& default_audio_rtp_header_extensions, + const RtpHeaderExtensions& rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { @@ -2677,7 +2697,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( if (!CreateMediaContentAnswer( offer_audio_description, media_description_options, session_options, sdes_policy, GetCryptos(current_content), - filtered_rtp_header_extensions(default_audio_rtp_header_extensions), + filtered_rtp_header_extensions(rtp_header_extensions), ssrc_generator(), enable_encrypted_rtp_header_extensions_, current_streams, bundle_enabled, audio_answer.get())) { return false; // Fails the session setup. diff --git a/third_party/libwebrtc/pc/media_session.h b/third_party/libwebrtc/pc/media_session.h index 6548f9c4361c6..87f04c779fee5 100644 --- a/third_party/libwebrtc/pc/media_session.h +++ b/third_party/libwebrtc/pc/media_session.h @@ -285,7 +285,7 @@ class MediaSessionDescriptionFactory { const SessionDescription* current_description, const TransportInfo* bundle_transport, const AudioCodecs& audio_codecs, - const RtpHeaderExtensions& default_audio_rtp_header_extensions, + const RtpHeaderExtensions& rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const; @@ -299,7 +299,7 @@ class MediaSessionDescriptionFactory { const SessionDescription* current_description, const TransportInfo* bundle_transport, const VideoCodecs& video_codecs, - const RtpHeaderExtensions& default_video_rtp_header_extensions, + const RtpHeaderExtensions& rtp_header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const; diff --git a/third_party/libwebrtc/pc/media_session_unittest.cc b/third_party/libwebrtc/pc/media_session_unittest.cc index 8f38f6a1b4912..6ba5032092b07 100644 --- a/third_party/libwebrtc/pc/media_session_unittest.cc +++ b/third_party/libwebrtc/pc/media_session_unittest.cc @@ -2018,7 +2018,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, } TEST_F(MediaSessionDescriptionFactoryTest, - AppendsStoppedExtensionIfKnownAndPresentInTheOffer) { + AllowsStoppedExtensionsToBeRemovedFromSubsequentOffer) { MediaSessionOptions opts; AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video", RtpTransceiverDirection::kSendRecv, kActive, @@ -2026,12 +2026,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, opts.media_description_options.back().header_extensions = { webrtc::RtpHeaderExtensionCapability("uri1", 1, RtpTransceiverDirection::kSendRecv), - webrtc::RtpHeaderExtensionCapability("uri2", 1, + webrtc::RtpHeaderExtensionCapability("uri2", 2, RtpTransceiverDirection::kSendRecv)}; auto offer = f1_.CreateOffer(opts, nullptr); - // Now add "uri2" as stopped to the options verify that the offer contains - // uri2 since it's already present since before. + // Check that a subsequent offer after setting "uri2" to stopped no longer + // contains the extension. opts.media_description_options.back().header_extensions = { webrtc::RtpHeaderExtensionCapability("uri1", 1, RtpTransceiverDirection::kSendRecv), @@ -2043,8 +2043,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, ElementsAre(Property( &ContentInfo::media_description, Pointee(Property(&MediaContentDescription::rtp_header_extensions, - ElementsAre(Field(&RtpExtension::uri, "uri1"), - Field(&RtpExtension::uri, "uri2"))))))); + ElementsAre(Field(&RtpExtension::uri, "uri1"))))))); } TEST_F(MediaSessionDescriptionFactoryTest, diff --git a/third_party/libwebrtc/pc/peer_connection.cc b/third_party/libwebrtc/pc/peer_connection.cc index 38e52b6a13e62..f7aec9ebcca83 100644 --- a/third_party/libwebrtc/pc/peer_connection.cc +++ b/third_party/libwebrtc/pc/peer_connection.cc @@ -24,6 +24,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/jsep_ice_candidate.h" +#include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/rtp_transceiver_direction.h" #include "api/uma_metrics.h" @@ -542,6 +543,10 @@ PeerConnection::~PeerConnection() { sdp_handler_->PrepareForShutdown(); } + // In case `Close()` wasn't called, always make sure the controller cancels + // potentially pending operations. + data_channel_controller_.PrepareForShutdown(); + // Need to stop transceivers before destroying the stats collector because // AudioRtpSender has a reference to the LegacyStatsCollector it will update // when stopping. @@ -572,7 +577,7 @@ PeerConnection::~PeerConnection() { transport_controller_copy_ = nullptr; network_thread()->BlockingCall([this] { RTC_DCHECK_RUN_ON(network_thread()); - TeardownDataChannelTransport_n(); + TeardownDataChannelTransport_n(RTCError::OK()); transport_controller_.reset(); port_allocator_.reset(); if (network_thread_safety_) @@ -587,6 +592,8 @@ PeerConnection::~PeerConnection() { // The event log must outlive call (and any other object that uses it). event_log_.reset(); }); + + data_channel_controller_.PrepareForShutdown(); } RTCError PeerConnection::Initialize( @@ -699,6 +706,7 @@ JsepTransportController* PeerConnection::InitializeTransportController_n( : options_.crypto_options; config.transport_observer = this; config.rtcp_handler = InitializeRtcpCallback(); + config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler(); config.event_log = event_log_ptr_; #if defined(ENABLE_EXTERNAL_AUTH) config.enable_external_auth = true; @@ -720,16 +728,13 @@ JsepTransportController* PeerConnection::InitializeTransportController_n( config.field_trials = trials_.get(); - transport_controller_.reset( - new JsepTransportController(network_thread(), port_allocator_.get(), - async_dns_resolver_factory_.get(), config)); + transport_controller_.reset(new JsepTransportController( + network_thread(), port_allocator_.get(), + async_dns_resolver_factory_.get(), std::move(config))); transport_controller_->SubscribeIceConnectionState( [this](cricket::IceConnectionState s) { RTC_DCHECK_RUN_ON(network_thread()); - if (s == cricket::kIceConnectionConnected) { - ReportTransportStats(); - } signaling_thread()->PostTask( SafeTask(signaling_thread_safety_.flag(), [this, s]() { RTC_DCHECK_RUN_ON(signaling_thread()); @@ -1392,24 +1397,32 @@ PeerConnection::CreateDataChannelOrError(const std::string& label, RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel"); + if (IsClosed()) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE, + "CreateDataChannelOrError: PeerConnection is closed."); + } + bool first_datachannel = !data_channel_controller_.HasUsedDataChannels(); - std::unique_ptr internal_config; + InternalDataChannelInit internal_config; if (config) { - internal_config.reset(new InternalDataChannelInit(*config)); + internal_config = InternalDataChannelInit(*config); } - // TODO(bugs.webrtc.org/12796): Return a more specific error. - rtc::scoped_refptr channel( + + internal_config.fallback_ssl_role = sdp_handler_->GuessSslRole(); + RTCErrorOr> ret = data_channel_controller_.InternalCreateDataChannelWithProxy( - label, internal_config.get())); - if (!channel.get()) { - return RTCError(RTCErrorType::INTERNAL_ERROR, - "Data channel creation failed"); + label, internal_config); + if (!ret.ok()) { + return ret.MoveError(); } - // Trigger the onRenegotiationNeeded event for - // the first SCTP DataChannel. - if (first_datachannel) { + rtc::scoped_refptr channel = ret.MoveValue(); + + // Check the onRenegotiationNeeded event (with plan-b backward compat) + if (configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan || + (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED && + first_datachannel)) { sdp_handler_->UpdateNegotiationNeeded(); } NoteUsageEvent(UsageEvent::DATA_ADDED); @@ -1915,13 +1928,15 @@ void PeerConnection::Close() { event_log_.reset(); }); ReportUsagePattern(); - // The .h file says that observer can be discarded after close() returns. - // Make sure this is true. - observer_ = nullptr; // Signal shutdown to the sdp handler. This invalidates weak pointers for // internal pending callbacks. sdp_handler_->PrepareForShutdown(); + data_channel_controller_.PrepareForShutdown(); + + // The .h file says that observer can be discarded after close() returns. + // Make sure this is true. + observer_ = nullptr; } void PeerConnection::SetIceConnectionState(IceConnectionState new_state) { @@ -2100,23 +2115,25 @@ absl::optional PeerConnection::GetDataMid() const { return sctp_mid_s_; } -void PeerConnection::SetSctpDataMid(const std::string& mid) { +void PeerConnection::SetSctpDataInfo(absl::string_view mid, + absl::string_view transport_name) { RTC_DCHECK_RUN_ON(signaling_thread()); - sctp_mid_s_ = mid; + sctp_mid_s_ = std::string(mid); + SetSctpTransportName(std::string(transport_name)); } -void PeerConnection::ResetSctpDataMid() { +void PeerConnection::ResetSctpDataInfo() { RTC_DCHECK_RUN_ON(signaling_thread()); sctp_mid_s_.reset(); SetSctpTransportName(""); } void PeerConnection::OnSctpDataChannelStateChanged( - DataChannelInterface* channel, + int channel_id, DataChannelInterface::DataState state) { RTC_DCHECK_RUN_ON(signaling_thread()); if (stats_collector_) - stats_collector_->OnSctpDataChannelStateChanged(channel, state); + stats_collector_->OnSctpDataChannelStateChanged(channel_id, state); } PeerConnection::InitializePortAllocatorResult @@ -2229,50 +2246,10 @@ void PeerConnection::StopRtcEventLog_w() { } } -bool PeerConnection::GetSctpSslRole(rtc::SSLRole* role) { - RTC_DCHECK_RUN_ON(signaling_thread()); - if (!sctp_mid_s_ || !data_channel_controller_.data_channel_transport()) { - RTC_LOG(LS_INFO) << "Non-rejected SCTP m= section is needed to get the " - "SSL Role of the SCTP transport."; - return false; - } - - absl::optional dtls_role = network_thread()->BlockingCall( - [this, is_caller = sdp_handler_->is_caller()] { - RTC_DCHECK_RUN_ON(network_thread()); - return GetSctpSslRole_n(is_caller); - }); - if (!dtls_role) { - return false; - } - - *role = *dtls_role; - return true; -} - -absl::optional PeerConnection::GetSctpSslRole_n( - absl::optional is_caller) { +absl::optional PeerConnection::GetSctpSslRole_n() { RTC_DCHECK_RUN_ON(network_thread()); - if (!sctp_mid_n_) - return absl::nullopt; - - absl::optional dtls_role = - transport_controller_->GetDtlsRole(*sctp_mid_n_); - if (!dtls_role) { - if (!is_caller.has_value()) - return absl::nullopt; - - // This works fine if we are the offerer, but can be a mistake if - // we are the answerer and the remote offer is ACTIVE. In that - // case, we will guess the role wrong. - // TODO(bugs.webrtc.org/13668): Check if this actually happens. - RTC_LOG(LS_ERROR) - << "Possible risk: DTLS role guesser is active, is_caller is " - << *is_caller; - dtls_role = *is_caller ? rtc::SSL_SERVER : rtc::SSL_CLIENT; - } - - return dtls_role; + return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_) + : absl::nullopt; } bool PeerConnection::GetSslRole(const std::string& content_name, @@ -2313,7 +2290,7 @@ bool PeerConnection::GetTransportDescription( } std::vector PeerConnection::GetDataChannelStats() const { - RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK_RUN_ON(network_thread()); return data_channel_controller_.GetDataChannelStats(); } @@ -2421,6 +2398,20 @@ void PeerConnection::OnTransportControllerConnectionState( case cricket::kIceConnectionConnected: RTC_LOG(LS_INFO) << "Changing to ICE connected state because " "all transports are writable."; + { + std::vector transceivers; + if (ConfiguredForMedia()) { + transceivers = rtp_manager()->transceivers()->List(); + } + + network_thread()->PostTask( + SafeTask(network_thread_safety_, + [this, transceivers = std::move(transceivers)] { + RTC_DCHECK_RUN_ON(network_thread()); + ReportTransportStats(std::move(transceivers)); + })); + } + SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected); NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED); break; @@ -2538,40 +2529,35 @@ absl::optional PeerConnection::GetAudioDeviceStats() { return absl::nullopt; } -bool PeerConnection::SetupDataChannelTransport_n(const std::string& mid) { +absl::optional PeerConnection::SetupDataChannelTransport_n( + absl::string_view mid) { + sctp_mid_n_ = std::string(mid); DataChannelTransportInterface* transport = - transport_controller_->GetDataChannelTransport(mid); + transport_controller_->GetDataChannelTransport(*sctp_mid_n_); if (!transport) { RTC_LOG(LS_ERROR) << "Data channel transport is not available for data channels, mid=" << mid; - return false; + sctp_mid_n_ = absl::nullopt; + return absl::nullopt; } - RTC_LOG(LS_INFO) << "Setting up data channel transport for mid=" << mid; - data_channel_controller_.set_data_channel_transport(transport); - data_channel_controller_.SetupDataChannelTransport_n(); - sctp_mid_n_ = mid; + absl::optional transport_name; cricket::DtlsTransportInternal* dtls_transport = - transport_controller_->GetDtlsTransport(mid); + transport_controller_->GetDtlsTransport(*sctp_mid_n_); if (dtls_transport) { - signaling_thread()->PostTask( - SafeTask(signaling_thread_safety_.flag(), - [this, name = dtls_transport->transport_name()] { - RTC_DCHECK_RUN_ON(signaling_thread()); - SetSctpTransportName(std::move(name)); - })); - } - - // Note: setting the data sink and checking initial state must be done last, - // after setting up the data channel. Setting the data sink may trigger - // callbacks to PeerConnection which require the transport to be completely - // set up (eg. OnReadyToSend()). - transport->SetDataSink(&data_channel_controller_); - return true; + transport_name = dtls_transport->transport_name(); + } else { + // Make sure we still set a valid string. + transport_name = std::string(""); + } + + data_channel_controller_.SetupDataChannelTransport_n(transport); + + return transport_name; } -void PeerConnection::TeardownDataChannelTransport_n() { +void PeerConnection::TeardownDataChannelTransport_n(RTCError error) { if (sctp_mid_n_) { // `sctp_mid_` may still be active through an SCTP transport. If not, unset // it. @@ -2580,7 +2566,7 @@ void PeerConnection::TeardownDataChannelTransport_n() { sctp_mid_n_.reset(); } - data_channel_controller_.TeardownDataChannelTransport_n(); + data_channel_controller_.TeardownDataChannelTransport_n(error); } // Returns false if bundle is enabled and rtcp_mux is disabled. @@ -2768,20 +2754,18 @@ void PeerConnection::OnTransportControllerGatheringState( } // Runs on network_thread(). -void PeerConnection::ReportTransportStats() { +void PeerConnection::ReportTransportStats( + std::vector transceivers) { TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats"); rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; std::map> media_types_by_transport_name; - if (ConfiguredForMedia()) { - for (const auto& transceiver : - rtp_manager()->transceivers()->UnsafeList()) { - if (transceiver->internal()->channel()) { - std::string transport_name( - transceiver->internal()->channel()->transport_name()); - media_types_by_transport_name[transport_name].insert( - transceiver->media_type()); - } + for (const auto& transceiver : transceivers) { + if (transceiver->internal()->channel()) { + std::string transport_name( + transceiver->internal()->channel()->transport_name()); + media_types_by_transport_name[transport_name].insert( + transceiver->media_type()); } } @@ -3024,4 +3008,21 @@ PeerConnection::InitializeRtcpCallback() { }; } +std::function +PeerConnection::InitializeUnDemuxablePacketHandler() { + RTC_DCHECK_RUN_ON(network_thread()); + return [this](const RtpPacketReceived& parsed_packet) { + worker_thread()->PostTask( + SafeTask(worker_thread_safety_, [this, parsed_packet]() { + // Deliver the packet anyway to Call to allow Call to do BWE. + // Even if there is no media receiver, the packet has still + // been received on the network and has been correcly parsed. + call_ptr_->Receiver()->DeliverRtpPacket( + MediaType::ANY, parsed_packet, + /*undemuxable_packet_handler=*/ + [](const RtpPacketReceived& packet) { return false; }); + })); + }; +} + } // namespace webrtc diff --git a/third_party/libwebrtc/pc/peer_connection.h b/third_party/libwebrtc/pc/peer_connection.h index 1e50ec891bb3b..21b9a5a4306e3 100644 --- a/third_party/libwebrtc/pc/peer_connection.h +++ b/third_party/libwebrtc/pc/peer_connection.h @@ -51,6 +51,7 @@ #include "api/transport/enums.h" #include "api/turn_customizer.h" #include "call/call.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "p2p/base/ice_transport_internal.h" #include "p2p/base/port.h" #include "p2p/base/port_allocator.h" @@ -314,12 +315,10 @@ class PeerConnection : public PeerConnectionInternal, sdp_handler_->signaling_state() == PeerConnectionInterface::kClosed; } // Get current SSL role used by SCTP's underlying transport. - bool GetSctpSslRole(rtc::SSLRole* role) override; - absl::optional GetSctpSslRole_n( - absl::optional is_caller) override; + absl::optional GetSctpSslRole_n() override; void OnSctpDataChannelStateChanged( - DataChannelInterface* channel, + int channel_id, DataChannelInterface::DataState state) override; bool ShouldFireNegotiationNeededEvent(uint32_t event_id) override; @@ -403,9 +402,10 @@ class PeerConnection : public PeerConnectionInternal, // channels are configured this will return nullopt. absl::optional GetDataMid() const override; - void SetSctpDataMid(const std::string& mid) override; + void SetSctpDataInfo(absl::string_view mid, + absl::string_view transport_name) override; - void ResetSctpDataMid() override; + void ResetSctpDataInfo() override; // Asynchronously calls SctpTransport::Start() on the network thread for // `sctp_mid()` if set. Called as part of setting the local description. @@ -433,9 +433,10 @@ class PeerConnection : public PeerConnectionInternal, // this session. bool SrtpRequired() const override; - bool SetupDataChannelTransport_n(const std::string& mid) override + absl::optional SetupDataChannelTransport_n( + absl::string_view mid) override RTC_RUN_ON(network_thread()); + void TeardownDataChannelTransport_n(RTCError error) override RTC_RUN_ON(network_thread()); - void TeardownDataChannelTransport_n() override RTC_RUN_ON(network_thread()); const FieldTrialsView& trials() const override { return *trials_; } @@ -568,7 +569,8 @@ class PeerConnection : public PeerConnectionInternal, // Invoked when TransportController connection completion is signaled. // Reports stats for all transports in use. - void ReportTransportStats() RTC_RUN_ON(network_thread()); + void ReportTransportStats(std::vector transceivers) + RTC_RUN_ON(network_thread()); // Gather the usage of IPv4/IPv6 as best connection. static void ReportBestConnectionState(const cricket::TransportStats& stats); @@ -602,6 +604,9 @@ class PeerConnection : public PeerConnectionInternal, int64_t packet_time_us)> InitializeRtcpCallback(); + std::function + InitializeUnDemuxablePacketHandler(); + const rtc::scoped_refptr context_; // Field trials active for this PeerConnection is the first of: // a) Specified in PeerConnectionDependencies (owned). diff --git a/third_party/libwebrtc/pc/peer_connection_bundle_unittest.cc b/third_party/libwebrtc/pc/peer_connection_bundle_unittest.cc index ad3d1185103a1..a71b513865962 100644 --- a/third_party/libwebrtc/pc/peer_connection_bundle_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_bundle_unittest.cc @@ -34,8 +34,16 @@ #include "api/stats/rtc_stats.h" #include "api/stats/rtc_stats_report.h" #include "api/stats/rtcstats_objects.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/stream_params.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -214,7 +222,12 @@ class PeerConnectionBundleBaseTest : public ::testing::Test { rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), rtc::scoped_refptr(FakeAudioCaptureModule::Create()), CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(), + std::make_unique>(), + std::make_unique>(), nullptr /* audio_mixer */, nullptr /* audio_processing */); } diff --git a/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc b/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc index fae74681fc4ee..1aedbf295fe2a 100644 --- a/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_crypto_unittest.cc @@ -28,8 +28,16 @@ #include "api/jsep.h" #include "api/peer_connection_interface.h" #include "api/scoped_refptr.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "p2p/base/fake_port_allocator.h" @@ -80,9 +88,14 @@ class PeerConnectionCryptoBaseTest : public ::testing::Test { pc_factory_ = CreatePeerConnectionFactory( rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), FakeAudioCaptureModule::Create(), CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory(), CreateBuiltinVideoEncoderFactory(), - CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + CreateBuiltinAudioDecoderFactory(), + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); } WrapperPtr CreatePeerConnection() { diff --git a/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc b/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc new file mode 100644 index 0000000000000..8e86724179d40 --- /dev/null +++ b/third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc @@ -0,0 +1,940 @@ +/* + * 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 +#include + +#include "api/audio_codecs/builtin_audio_decoder_factory.h" +#include "api/audio_codecs/builtin_audio_encoder_factory.h" +#include "api/audio_codecs/opus_audio_decoder_factory.h" +#include "api/audio_codecs/opus_audio_encoder_factory.h" +#include "api/rtp_parameters.h" +#include "api/stats/rtcstats_objects.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" +#include "pc/sdp_utils.h" +#include "pc/simulcast_description.h" +#include "pc/test/mock_peer_connection_observers.h" +#include "pc/test/peer_connection_test_wrapper.h" +#include "pc/test/simulcast_layer_util.h" +#include "rtc_base/gunit.h" +#include "rtc_base/physical_socket_server.h" +#include "test/gmock.h" +#include "test/gtest.h" + +using ::testing::Eq; +using ::testing::Optional; +using ::testing::SizeIs; +using ::testing::StrCaseEq; +using ::testing::StrEq; + +namespace webrtc { + +namespace { + +constexpr TimeDelta kDefaultTimeout = TimeDelta::Seconds(5); +// Most tests pass in 20-30 seconds, but some tests take longer such as AV1 +// requiring additional ramp-up time (https://crbug.com/webrtc/15006) or SVC +// (LxTx_KEY) being slower than simulcast to send top spatial layer. +// TODO(https://crbug.com/webrtc/15076): Remove need for long rampup timeouts by +// using simulated time. +constexpr TimeDelta kLongTimeoutForRampingUp = TimeDelta::Minutes(1); + +struct StringParamToString { + std::string operator()(const ::testing::TestParamInfo& info) { + return info.param; + } +}; + +// RTX, RED and FEC are reliability mechanisms used in combinations with other +// codecs, but are not themselves a specific codec. Typically you don't want to +// filter these out of the list of codec preferences. +bool IsReliabilityMechanism(const webrtc::RtpCodecCapability& codec) { + return absl::EqualsIgnoreCase(codec.name, cricket::kRtxCodecName) || + absl::EqualsIgnoreCase(codec.name, cricket::kRedCodecName) || + absl::EqualsIgnoreCase(codec.name, cricket::kUlpfecCodecName); +} + +std::string GetCurrentCodecMimeType( + rtc::scoped_refptr report, + const webrtc::RTCOutboundRtpStreamStats& outbound_rtp) { + return outbound_rtp.codec_id.is_defined() + ? *report->GetAs(*outbound_rtp.codec_id) + ->mime_type + : ""; +} + +struct RidAndResolution { + std::string rid; + uint32_t width; + uint32_t height; +}; + +const webrtc::RTCOutboundRtpStreamStats* FindOutboundRtpByRid( + const std::vector& outbound_rtps, + const absl::string_view& rid) { + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->rid.is_defined() && *outbound_rtp->rid == rid) { + return outbound_rtp; + } + } + return nullptr; +} + +} // namespace + +class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { + public: + PeerConnectionEncodingsIntegrationTest() + : background_thread_(std::make_unique(&pss_)) { + RTC_CHECK(background_thread_->Start()); + } + + rtc::scoped_refptr CreatePc() { + auto pc_wrapper = rtc::make_ref_counted( + "pc", &pss_, background_thread_.get(), background_thread_.get()); + pc_wrapper->CreatePc({}, webrtc::CreateOpusAudioEncoderFactory(), + webrtc::CreateOpusAudioDecoderFactory()); + return pc_wrapper; + } + + rtc::scoped_refptr AddTransceiverWithSimulcastLayers( + rtc::scoped_refptr local, + rtc::scoped_refptr remote, + std::vector init_layers) { + rtc::scoped_refptr stream = + local->GetUserMedia( + /*audio=*/false, cricket::AudioOptions(), /*video=*/true, + {.width = 1280, .height = 720}); + rtc::scoped_refptr track = stream->GetVideoTracks()[0]; + + RTCErrorOr> + transceiver_or_error = local->pc()->AddTransceiver( + track, CreateTransceiverInit(init_layers)); + EXPECT_TRUE(transceiver_or_error.ok()); + return transceiver_or_error.value(); + } + + bool HasSenderVideoCodecCapability( + rtc::scoped_refptr pc_wrapper, + absl::string_view codec_name) { + std::vector codecs = + pc_wrapper->pc_factory() + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + .codecs; + return std::find_if(codecs.begin(), codecs.end(), + [&codec_name](const RtpCodecCapability& codec) { + return absl::EqualsIgnoreCase(codec.name, codec_name); + }) != codecs.end(); + } + + std::vector GetCapabilitiesAndRestrictToCodec( + rtc::scoped_refptr pc_wrapper, + absl::string_view codec_name) { + std::vector codecs = + pc_wrapper->pc_factory() + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + .codecs; + codecs.erase(std::remove_if(codecs.begin(), codecs.end(), + [&codec_name](const RtpCodecCapability& codec) { + return !IsReliabilityMechanism(codec) && + !absl::EqualsIgnoreCase(codec.name, + codec_name); + }), + codecs.end()); + RTC_DCHECK(std::find_if(codecs.begin(), codecs.end(), + [&codec_name](const RtpCodecCapability& codec) { + return absl::EqualsIgnoreCase(codec.name, + codec_name); + }) != codecs.end()); + return codecs; + } + + void ExchangeIceCandidates( + rtc::scoped_refptr local_pc_wrapper, + rtc::scoped_refptr remote_pc_wrapper) { + local_pc_wrapper->SignalOnIceCandidateReady.connect( + remote_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate); + remote_pc_wrapper->SignalOnIceCandidateReady.connect( + local_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate); + } + + void NegotiateWithSimulcastTweaks( + rtc::scoped_refptr local_pc_wrapper, + rtc::scoped_refptr remote_pc_wrapper, + std::vector init_layers) { + // Create and set offer for `local_pc_wrapper`. + std::unique_ptr offer = + CreateOffer(local_pc_wrapper); + rtc::scoped_refptr p1 = + SetLocalDescription(local_pc_wrapper, offer.get()); + // Modify the offer before handoff because `remote_pc_wrapper` only supports + // receiving singlecast. + cricket::SimulcastDescription simulcast_description = + RemoveSimulcast(offer.get()); + rtc::scoped_refptr p2 = + SetRemoteDescription(remote_pc_wrapper, offer.get()); + EXPECT_TRUE(Await({p1, p2})); + + // Create and set answer for `remote_pc_wrapper`. + std::unique_ptr answer = + CreateAnswer(remote_pc_wrapper); + p1 = SetLocalDescription(remote_pc_wrapper, answer.get()); + // Modify the answer before handoff because `local_pc_wrapper` should still + // send simulcast. + cricket::MediaContentDescription* mcd_answer = + answer->description()->contents()[0].media_description(); + mcd_answer->mutable_streams().clear(); + std::vector simulcast_layers = + simulcast_description.send_layers().GetAllLayers(); + cricket::SimulcastLayerList& receive_layers = + mcd_answer->simulcast_description().receive_layers(); + for (const auto& layer : simulcast_layers) { + receive_layers.AddLayer(layer); + } + p2 = SetRemoteDescription(local_pc_wrapper, answer.get()); + EXPECT_TRUE(Await({p1, p2})); + } + + rtc::scoped_refptr GetStats( + rtc::scoped_refptr pc_wrapper) { + auto callback = rtc::make_ref_counted(); + pc_wrapper->pc()->GetStats(callback.get()); + EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout.ms()); + return callback->report(); + } + + bool HasOutboundRtpBytesSent( + rtc::scoped_refptr pc_wrapper, + size_t num_layers) { + return HasOutboundRtpBytesSent(pc_wrapper, num_layers, num_layers); + } + + bool HasOutboundRtpBytesSent( + rtc::scoped_refptr pc_wrapper, + size_t num_layers, + size_t num_active_layers) { + rtc::scoped_refptr report = GetStats(pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + if (outbound_rtps.size() != num_layers) { + return false; + } + size_t num_sending_layers = 0; + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->bytes_sent.is_defined() && + *outbound_rtp->bytes_sent > 0u) { + ++num_sending_layers; + } + } + return num_sending_layers == num_active_layers; + } + + bool HasOutboundRtpWithRidAndScalabilityMode( + rtc::scoped_refptr pc_wrapper, + absl::string_view rid, + absl::string_view expected_scalability_mode, + uint32_t frame_height) { + rtc::scoped_refptr report = GetStats(pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + auto* outbound_rtp = FindOutboundRtpByRid(outbound_rtps, rid); + if (!outbound_rtp || !outbound_rtp->scalability_mode.is_defined() || + *outbound_rtp->scalability_mode != expected_scalability_mode) { + return false; + } + if (outbound_rtp->frame_height.is_defined()) { + RTC_LOG(LS_INFO) << "Waiting for target resolution (" << frame_height + << "p). Currently at " << *outbound_rtp->frame_height + << "p..."; + } else { + RTC_LOG(LS_INFO) + << "Waiting for target resolution. No frames encoded yet..."; + } + if (!outbound_rtp->frame_height.is_defined() || + *outbound_rtp->frame_height != frame_height) { + // Sleep to avoid log spam when this is used in ASSERT_TRUE_WAIT(). + rtc::Thread::Current()->SleepMs(1000); + return false; + } + return true; + } + + bool OutboundRtpResolutionsAreLessThanOrEqualToExpectations( + rtc::scoped_refptr pc_wrapper, + std::vector resolutions) { + rtc::scoped_refptr report = GetStats(pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + for (const RidAndResolution& resolution : resolutions) { + const RTCOutboundRtpStreamStats* outbound_rtp = nullptr; + if (!resolution.rid.empty()) { + outbound_rtp = FindOutboundRtpByRid(outbound_rtps, resolution.rid); + } else if (outbound_rtps.size() == 1u) { + outbound_rtp = outbound_rtps[0]; + } + if (!outbound_rtp || !outbound_rtp->frame_width.is_defined() || + !outbound_rtp->frame_height.is_defined()) { + // RTP not found by rid or has not encoded a frame yet. + RTC_LOG(LS_ERROR) << "rid=" << resolution.rid << " does not have " + << "resolution metrics"; + return false; + } + if (*outbound_rtp->frame_width > resolution.width || + *outbound_rtp->frame_height > resolution.height) { + RTC_LOG(LS_ERROR) << "rid=" << resolution.rid << " is " + << *outbound_rtp->frame_width << "x" + << *outbound_rtp->frame_height + << ", this is greater than the " + << "expected " << resolution.width << "x" + << resolution.height; + return false; + } + } + return true; + } + + protected: + std::unique_ptr CreateOffer( + rtc::scoped_refptr pc_wrapper) { + auto observer = + rtc::make_ref_counted(); + pc_wrapper->pc()->CreateOffer(observer.get(), {}); + EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); + return observer->MoveDescription(); + } + + std::unique_ptr CreateAnswer( + rtc::scoped_refptr pc_wrapper) { + auto observer = + rtc::make_ref_counted(); + pc_wrapper->pc()->CreateAnswer(observer.get(), {}); + EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); + return observer->MoveDescription(); + } + + rtc::scoped_refptr SetLocalDescription( + rtc::scoped_refptr pc_wrapper, + SessionDescriptionInterface* sdp) { + auto observer = rtc::make_ref_counted(); + pc_wrapper->pc()->SetLocalDescription( + observer.get(), CloneSessionDescription(sdp).release()); + return observer; + } + + rtc::scoped_refptr SetRemoteDescription( + rtc::scoped_refptr pc_wrapper, + SessionDescriptionInterface* sdp) { + auto observer = rtc::make_ref_counted(); + pc_wrapper->pc()->SetRemoteDescription( + observer.get(), CloneSessionDescription(sdp).release()); + return observer; + } + + // To avoid ICE candidates arriving before the remote endpoint has received + // the offer it is important to SetLocalDescription() and + // SetRemoteDescription() are kicked off without awaiting in-between. This + // helper is used to await multiple observers. + bool Await(std::vector> + observers) { + for (auto& observer : observers) { + EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); + if (!observer->result()) { + return false; + } + } + return true; + } + + rtc::PhysicalSocketServer pss_; + std::unique_ptr background_thread_; +}; + +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP8_SingleEncodingDefaultsToL1T1) { + 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); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); + transceiver->SetCodecPreferences(codecs); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Wait until media is flowing. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), + kDefaultTimeout.ms()); + EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( + local_pc_wrapper, {{"", 1280, 720}})); + // Verify codec and scalability mode. + 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("L1T1")); +} + +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP8_RejectsSvcAndDefaultsToL1T1) { + 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 codecs restricts what SetParameters() will accept or reject. + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); + transceiver->SetCodecPreferences(codecs); + // 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(); + 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_FALSE(sender->SetParameters(parameters).ok()); + // `scalability_mode` remains unset because SetParameters() failed. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + 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("L1T1")); + // 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(absl::nullopt)); +} + +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP8_FallbackFromSvcResultsInL1T2) { + 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); + // Verify test assumption that VP8 is first in the list, but don't modify the + // codec preferences because we want the sender to think SVC is a possibility. + std::vector codecs = + local_pc_wrapper->pc_factory() + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + .codecs; + EXPECT_THAT(codecs[0].name, StrCaseEq("VP8")); + // Attempt SVC (L3T3_KEY), which is not possible with VP8, but the sender does + // not yet know which codec we'll use so the parameters will be accepted. + 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()); + // Verify fallback has not happened yet. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L3T3_KEY"))); + + // Negotiate, this results in VP8 being picked and fallback happening. + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + // `scalaiblity_mode` is assigned the fallback value "L1T2" which is different + // than the default of absl::nullopt. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L1T2"))); + + // Wait until media is flowing, no significant time needed because we only + // have one layer. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), + kDefaultTimeout.ms()); + // GetStats() confirms "L1T2" is used which is different than the "L1T1" + // default or the "L3T3_KEY" that was attempted. + 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")); +} + +// The legacy SVC path is triggered when VP9 us used, but `scalability_mode` has +// not been specified. +// TODO(https://crbug.com/webrtc/14889): When legacy VP9 SVC path has been +// deprecated and removed, update this test to assert that simulcast is used +// (i.e. VP9 is not treated differently than VP8). +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_LegacySvcWhenScalabilityModeNotSpecified) { + 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", "h", "q"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Wait until media is flowing. We only expect a single RTP stream. + // We expect to see bytes flowing almost immediately on the lowest layer. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), + kDefaultTimeout.ms()); + // Wait until scalability mode is reported and expected resolution reached. + // Ramp up time may be significant. + ASSERT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( + local_pc_wrapper, "f", "L3T3_KEY", 720), + kLongTimeoutForRampingUp.ms()); + + // Despite SVC being used on a single RTP stream, GetParameters() returns the + // three encodings that we configured earlier (this is not spec-compliant but + // it is how legacy SVC behaves). + rtc::scoped_refptr sender = transceiver->sender(); + std::vector encodings = + sender->GetParameters().encodings; + ASSERT_EQ(encodings.size(), 3u); + // When legacy SVC is used, `scalability_mode` is not specified. + EXPECT_FALSE(encodings[0].scalability_mode.has_value()); + EXPECT_FALSE(encodings[1].scalability_mode.has_value()); + EXPECT_FALSE(encodings[2].scalability_mode.has_value()); +} + +// The spec-compliant way to configure SVC for a single stream. The expected +// outcome is the same as for the legacy SVC case except that we only have one +// encoding in GetParameters(). +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_StandardSvcWithOnlyOneEncoding) { + 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); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + // Configure SVC, a.k.a. "L3T3_KEY". + 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, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Wait until media is flowing. We only expect a single RTP stream. + // We expect to see bytes flowing almost immediately on the lowest layer. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), + kDefaultTimeout.ms()); + EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( + local_pc_wrapper, {{"", 1280, 720}})); + // Verify codec and scalability mode. + 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/VP9")); + EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L3T3_KEY")); + + // GetParameters() is consistent with what we asked for and got. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L3T3_KEY"))); +} + +// The {active,inactive,inactive} case is technically simulcast but since we +// only have one active stream, we're able to do SVC (multiple spatial layers +// is not supported if multiple encodings are active). The expected outcome is +// the same as above except we end up with two inactive RTP streams which are +// observable in GetStats(). +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_StandardSvcWithSingleActiveEncoding) { + 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", "h", "q"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + // Configure SVC, a.k.a. "L3T3_KEY". + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[0].scalability_mode = "L3T3_KEY"; + parameters.encodings[0].scale_resolution_down_by = 1; + parameters.encodings[1].active = false; + parameters.encodings[2].active = false; + EXPECT_TRUE(sender->SetParameters(parameters).ok()); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Since the standard API is configuring simulcast we get three outbound-rtps, + // but only one is active. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u, 1u), + kDefaultTimeout.ms()); + // Wait until scalability mode is reported and expected resolution reached. + // Ramp up time is significant. + ASSERT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( + local_pc_wrapper, "f", "L3T3_KEY", 720), + kLongTimeoutForRampingUp.ms()); + + // GetParameters() is consistent with what we asked for and got. + parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L3T3_KEY"))); + EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value()); + EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value()); +} + +// Exercise common path where `scalability_mode` is not specified until after +// negotiation, requring us to recreate the stream when the number of streams +// changes from 1 (legacy SVC) to 3 (standard simulcast). +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_SwitchFromLegacySvcToStandardSingleActiveEncodingSvc) { + 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", "h", "q"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + + // The original negotiation triggers legacy SVC because we didn't specify + // any scalability mode. + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Switch to the standard mode. Despite only having a single active stream in + // both cases, this internally reconfigures from 1 stream to 3 streams. + // Test coverage for https://crbug.com/webrtc/15016. + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[0].active = true; + parameters.encodings[0].scalability_mode = "L2T2_KEY"; + parameters.encodings[0].scale_resolution_down_by = 2.0; + parameters.encodings[1].active = false; + parameters.encodings[1].scalability_mode = absl::nullopt; + parameters.encodings[2].active = false; + parameters.encodings[2].scalability_mode = absl::nullopt; + sender->SetParameters(parameters); + + // Since the standard API is configuring simulcast we get three outbound-rtps, + // but only one is active. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u, 1u), + kDefaultTimeout.ms()); + // Wait until scalability mode is reported and expected resolution reached. + // Ramp up time may be significant. + ASSERT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( + local_pc_wrapper, "f", "L2T2_KEY", 720 / 2), + kLongTimeoutForRampingUp.ms()); + + // GetParameters() does not report any fallback. + parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L2T2_KEY"))); + EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value()); + EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value()); +} + +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_AllLayersInactive_LegacySvc) { + 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", "h", "q"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + + // Legacy SVC mode and all layers inactive. + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[0].active = false; + parameters.encodings[1].active = false; + parameters.encodings[2].active = false; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Ensure no media is flowing (1 second should be enough). + rtc::Thread::Current()->SleepMs(1000); + rtc::scoped_refptr report = GetStats(local_pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + ASSERT_THAT(outbound_rtps, SizeIs(1u)); + EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u); +} + +TEST_F(PeerConnectionEncodingsIntegrationTest, + VP9_AllLayersInactive_StandardSvc) { + 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", "h", "q"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + transceiver->SetCodecPreferences(codecs); + + // Standard mode and all layers inactive. + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[0].scalability_mode = "L3T3_KEY"; + parameters.encodings[0].scale_resolution_down_by = 1; + parameters.encodings[0].active = false; + parameters.encodings[1].active = false; + parameters.encodings[2].active = false; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Ensure no media is flowing (1 second should be enough). + rtc::Thread::Current()->SleepMs(1000); + rtc::scoped_refptr report = GetStats(local_pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + ASSERT_THAT(outbound_rtps, SizeIs(3u)); + EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u); + EXPECT_EQ(*outbound_rtps[1]->bytes_sent, 0u); + EXPECT_EQ(*outbound_rtps[2]->bytes_sent, 0u); +} + +// Tests that use the standard path (specifying both `scalability_mode` and +// `scale_resolution_down_by`) should pass for all codecs. +class PeerConnectionEncodingsIntegrationParameterizedTest + : public PeerConnectionEncodingsIntegrationTest, + public ::testing::WithParamInterface { + public: + PeerConnectionEncodingsIntegrationParameterizedTest() + : codec_name_(GetParam()), mime_type_("video/" + codec_name_) {} + + // Work-around for the fact that whether or not AV1 is supported is not known + // at compile-time so we have to skip tests early if missing. + // TODO(https://crbug.com/webrtc/15011): Increase availability of AV1 or make + // it possible to check support at compile-time. + bool SkipTestDueToAv1Missing( + rtc::scoped_refptr local_pc_wrapper) { + if (codec_name_ == "AV1" && + !HasSenderVideoCodecCapability(local_pc_wrapper, "AV1")) { + RTC_LOG(LS_WARNING) << "\n***\nAV1 is not available, skipping test.\n***"; + return true; + } + return false; + } + + protected: + const std::string codec_name_; // E.g. "VP9" + const std::string mime_type_; // E.g. "video/VP9" +}; + +TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, AllLayersInactive) { + 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({"f", "h", "q"}, /*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); + + // Standard mode and all layers inactive. + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[0].scalability_mode = "L1T3"; + parameters.encodings[0].scale_resolution_down_by = 1; + parameters.encodings[0].active = false; + parameters.encodings[1].active = false; + parameters.encodings[2].active = false; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Ensure no media is flowing (1 second should be enough). + rtc::Thread::Current()->SleepMs(1000); + rtc::scoped_refptr report = GetStats(local_pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + ASSERT_THAT(outbound_rtps, SizeIs(3u)); + EXPECT_EQ(*outbound_rtps[0]->bytes_sent, 0u); + EXPECT_EQ(*outbound_rtps[1]->bytes_sent, 0u); + EXPECT_EQ(*outbound_rtps[2]->bytes_sent, 0u); +} + +TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) { + 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({"f", "h", "q"}, /*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)); + parameters.encodings[0].scalability_mode = "L1T3"; + parameters.encodings[0].scale_resolution_down_by = 4; + parameters.encodings[1].scalability_mode = "L1T3"; + parameters.encodings[1].scale_resolution_down_by = 2; + parameters.encodings[2].scalability_mode = "L1T3"; + parameters.encodings[2].scale_resolution_down_by = 1; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // GetParameters() does not report any fallback. + parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + EXPECT_THAT(parameters.encodings[0].scalability_mode, + Optional(std::string("L1T3"))); + EXPECT_THAT(parameters.encodings[1].scalability_mode, + Optional(std::string("L1T3"))); + EXPECT_THAT(parameters.encodings[2].scalability_mode, + Optional(std::string("L1T3"))); + + // Wait until media is flowing on all three layers. + // Ramp up time is needed before all three layers are sending. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u), + kLongTimeoutForRampingUp.ms()); + EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( + local_pc_wrapper, {{"f", 320, 180}, {"h", 640, 360}, {"q", 1280, 720}})); + // Verify codec and scalability mode. + rtc::scoped_refptr report = GetStats(local_pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + ASSERT_THAT(outbound_rtps, SizeIs(3u)); + EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), + StrCaseEq(mime_type_)); + EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]), + StrCaseEq(mime_type_)); + EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]), + StrCaseEq(mime_type_)); + EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3")); + EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3")); + EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); +} + +INSTANTIATE_TEST_SUITE_P(StandardPath, + PeerConnectionEncodingsIntegrationParameterizedTest, + ::testing::Values("VP8", + "VP9", +#if defined(WEBRTC_USE_H264) + "H264", +#endif // defined(WEBRTC_USE_H264) + "AV1"), + StringParamToString()); + +} // namespace webrtc diff --git a/third_party/libwebrtc/pc/peer_connection_end_to_end_unittest.cc b/third_party/libwebrtc/pc/peer_connection_end_to_end_unittest.cc index 89387f94017b8..a21d455ec5a8b 100644 --- a/third_party/libwebrtc/pc/peer_connection_end_to_end_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_end_to_end_unittest.cc @@ -694,37 +694,6 @@ TEST_P(PeerConnectionEndToEndTest, CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1); } -// Similar to the above test, but don't wait for the first channel to finish -// closing before creating the second one. -TEST_P(PeerConnectionEndToEndTest, - DataChannelFromOpenWorksWhilePreviousChannelClosing) { - CreatePcs(webrtc::MockAudioEncoderFactory::CreateEmptyFactory(), - webrtc::MockAudioDecoderFactory::CreateEmptyFactory()); - - webrtc::DataChannelInit init; - rtc::scoped_refptr caller_dc( - caller_->CreateDataChannel("data", init)); - - Negotiate(); - WaitForConnection(); - - WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 0); - int first_channel_id = caller_dc->id(); - caller_dc->Close(); - - // Immediately create a new channel, before waiting for the previous one to - // transition to "closed". - caller_dc = caller_->CreateDataChannel("data2", init); - WaitForDataChannelsToOpen(caller_dc.get(), callee_signaled_data_channels_, 1); - // Since the second channel was created while the first was still closing, - // it should have been assigned a different ID. - EXPECT_NE(first_channel_id, caller_dc->id()); - TestDataChannelSendAndReceive(caller_dc.get(), - callee_signaled_data_channels_[1].get()); - - CloseDataChannels(caller_dc.get(), callee_signaled_data_channels_, 1); -} - // This tests that if a data channel is closed remotely while not referenced // by the application (meaning only the PeerConnection contributes to its // reference count), no memory access violation will occur. diff --git a/third_party/libwebrtc/pc/peer_connection_factory_unittest.cc b/third_party/libwebrtc/pc/peer_connection_factory_unittest.cc index b7fb726cc35d5..9c0ed4bb831d4 100644 --- a/third_party/libwebrtc/pc/peer_connection_factory_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_factory_unittest.cc @@ -10,6 +10,7 @@ #include "pc/peer_connection_factory.h" +#include #include #include @@ -21,8 +22,16 @@ #include "api/jsep.h" #include "api/media_stream_interface.h" #include "api/test/mock_packet_socket_factory.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/fake_frame_source.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -48,14 +57,8 @@ #include "pc/test/fake_rtc_certificate_generator.h" #include "pc/test/fake_video_track_renderer.h" -using webrtc::DataChannelInterface; -using webrtc::FakeVideoTrackRenderer; -using webrtc::MediaStreamInterface; -using webrtc::PeerConnectionFactoryInterface; -using webrtc::PeerConnectionInterface; -using webrtc::PeerConnectionObserver; -using webrtc::VideoTrackInterface; -using webrtc::VideoTrackSourceInterface; +namespace webrtc { +namespace { using ::testing::_; using ::testing::AtLeast; @@ -64,8 +67,6 @@ using ::testing::NiceMock; using ::testing::Return; using ::testing::UnorderedElementsAre; -namespace { - static const char kStunIceServer[] = "stun:stun.l.google.com:19302"; static const char kTurnIceServer[] = "turn:test.com:1234"; static const char kTurnIceServerWithTransport[] = @@ -120,8 +121,6 @@ class MockNetworkManager : public rtc::NetworkManager { (override)); }; -} // namespace - class PeerConnectionFactoryTest : public ::testing::Test { public: PeerConnectionFactoryTest() @@ -142,9 +141,13 @@ class PeerConnectionFactoryTest : public ::testing::Test { FakeAudioCaptureModule::Create()), webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); ASSERT_TRUE(factory_.get() != NULL); packet_socket_factory_.reset( @@ -274,8 +277,8 @@ TEST(PeerConnectionFactoryTestInternal, DISABLED_CreatePCUsingInternalModules) { nullptr /* signaling_thread */, nullptr /* default_adm */, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, + nullptr /* video_encoder_factory */, + nullptr /* video_decoder_factory */, nullptr /* audio_mixer */, nullptr /* audio_processing */)); NullPeerConnectionObserver observer; @@ -646,3 +649,6 @@ TEST(PeerConnectionFactoryDependenciesTest, UsesPacketSocketFactory) { called.Wait(kWaitTimeout); } + +} // namespace +} // namespace webrtc diff --git a/third_party/libwebrtc/pc/peer_connection_header_extension_unittest.cc b/third_party/libwebrtc/pc/peer_connection_header_extension_unittest.cc index 94d4401ca44e2..b1c6c3cfb5c7c 100644 --- a/third_party/libwebrtc/pc/peer_connection_header_extension_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_header_extension_unittest.cc @@ -199,6 +199,39 @@ TEST_P(PeerConnectionHeaderExtensionTest, OffersUnstoppedModifiedExtensions) { Field(&RtpExtension::uri, "uri3"))); } +TEST_P(PeerConnectionHeaderExtensionTest, AnswersUnstoppedModifiedExtensions) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc1 = + CreatePeerConnection(media_type, semantics); + std::unique_ptr pc2 = + CreatePeerConnection(media_type, semantics); + auto transceiver1 = pc1->AddTransceiver(media_type); + + auto offer = pc1->CreateOfferAndSetAsLocal( + PeerConnectionInterface::RTCOfferAnswerOptions()); + pc2->SetRemoteDescription(std::move(offer)); + + ASSERT_EQ(pc2->pc()->GetTransceivers().size(), 1u); + auto transceiver2 = pc2->pc()->GetTransceivers()[0]; + auto modified_extensions = transceiver2->GetHeaderExtensionsToNegotiate(); + // Don't offer uri4. + modified_extensions[3].direction = RtpTransceiverDirection::kStopped; + transceiver2->SetHeaderExtensionsToNegotiate(modified_extensions); + + auto answer = pc2->CreateAnswerAndSetAsLocal( + PeerConnectionInterface::RTCOfferAnswerOptions()); + EXPECT_THAT(answer->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"))); +} + TEST_P(PeerConnectionHeaderExtensionTest, NegotiatedExtensionsAreAccessible) { cricket::MediaType media_type; SdpSemantics semantics; @@ -235,6 +268,67 @@ TEST_P(PeerConnectionHeaderExtensionTest, NegotiatedExtensionsAreAccessible) { RtpTransceiverDirection::kStopped))); } +TEST_P(PeerConnectionHeaderExtensionTest, OfferedExtensionsArePerTransceiver) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc1 = + CreatePeerConnection(media_type, semantics); + auto transceiver1 = pc1->AddTransceiver(media_type); + auto modified_extensions = transceiver1->GetHeaderExtensionsToNegotiate(); + modified_extensions[3].direction = RtpTransceiverDirection::kStopped; + transceiver1->SetHeaderExtensionsToNegotiate(modified_extensions); + auto transceiver2 = pc1->AddTransceiver(media_type); + + auto session_description = pc1->CreateOffer(); + EXPECT_THAT(session_description->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"))); + EXPECT_THAT(session_description->description() + ->contents()[1] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"), + Field(&RtpExtension::uri, "uri4"))); +} + +TEST_P(PeerConnectionHeaderExtensionTest, RemovalAfterRenegotiation) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc1 = + CreatePeerConnection(media_type, semantics); + std::unique_ptr pc2 = + CreatePeerConnection(media_type, semantics); + auto transceiver1 = pc1->AddTransceiver(media_type); + + auto offer = pc1->CreateOfferAndSetAsLocal( + PeerConnectionInterface::RTCOfferAnswerOptions()); + pc2->SetRemoteDescription(std::move(offer)); + auto answer = pc2->CreateAnswerAndSetAsLocal( + PeerConnectionInterface::RTCOfferAnswerOptions()); + pc1->SetRemoteDescription(std::move(answer)); + + auto modified_extensions = transceiver1->GetHeaderExtensionsToNegotiate(); + modified_extensions[3].direction = RtpTransceiverDirection::kStopped; + transceiver1->SetHeaderExtensionsToNegotiate(modified_extensions); + auto session_description = pc1->CreateOffer(); + EXPECT_THAT(session_description->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"))); +} + TEST_P(PeerConnectionHeaderExtensionTest, StoppedByDefaultExtensionCanBeActivatedByRemoteSdp) { cricket::MediaType media_type; @@ -288,16 +382,23 @@ TEST_P(PeerConnectionHeaderExtensionTest, "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:" "AD:7E:77:43:2A:29:EC:93\r\n" "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n" - "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n" - "m=audio 9 RTP/AVPF 111\r\n" + "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n"; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + sdp += + "m=audio 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_audio_codec/8000\r\n"; + } else { + sdp += + "m=video 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_video_codec/90000\r\n"; + } + sdp += "c=IN IP4 0.0.0.0\r\n" "a=rtcp-mux\r\n" "a=sendonly\r\n" "a=mid:audio\r\n" - "a=rtpmap:111 fake_audio_codec/0\r\n" "a=setup:actpass\r\n" "a=extmap:1 urn:bogus\r\n"; - RTC_LOG(LS_ERROR) << sdp; auto offer = CreateSessionDescription(SdpType::kOffer, sdp); pc->SetRemoteDescription(std::move(offer)); pc->CreateAnswerAndSetAsLocal( @@ -314,6 +415,156 @@ TEST_P(PeerConnectionHeaderExtensionTest, } } +// These tests are regression tests for behavior that the API +// enables in a proper way. It conflicts with the behavior +// of the API to only offer non-stopped extensions. +TEST_P(PeerConnectionHeaderExtensionTest, + SdpMungingAnswerWithoutApiUsageEnablesExtensions) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc = + CreatePeerConnection(media_type, semantics); + std::string sdp = + "v=0\r\n" + "o=- 0 3 IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n" + "a=fingerprint:sha-256 " + "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:" + "AD:7E:77:43:2A:29:EC:93\r\n" + "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n" + "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n"; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + sdp += + "m=audio 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_audio_codec/8000\r\n"; + } else { + sdp += + "m=video 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_video_codec/90000\r\n"; + } + sdp += + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp-mux\r\n" + "a=sendrecv\r\n" + "a=mid:audio\r\n" + "a=setup:actpass\r\n" + "a=extmap:1 uri1\r\n"; + auto offer = CreateSessionDescription(SdpType::kOffer, sdp); + pc->SetRemoteDescription(std::move(offer)); + auto answer = + pc->CreateAnswer(PeerConnectionInterface::RTCOfferAnswerOptions()); + std::string modified_sdp; + ASSERT_TRUE(answer->ToString(&modified_sdp)); + modified_sdp += "a=extmap:1 uri1\r\n"; + auto modified_answer = + CreateSessionDescription(SdpType::kAnswer, modified_sdp); + ASSERT_TRUE(pc->SetLocalDescription(std::move(modified_answer))); + + auto session_description = pc->CreateOffer(); + EXPECT_THAT(session_description->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri1"), + Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"), + Field(&RtpExtension::uri, "uri4"))); +} + +TEST_P(PeerConnectionHeaderExtensionTest, + SdpMungingOfferWithoutApiUsageEnablesExtensions) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc = + CreatePeerConnection(media_type, semantics); + pc->AddTransceiver(media_type); + + auto offer = + pc->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions()); + std::string modified_sdp; + ASSERT_TRUE(offer->ToString(&modified_sdp)); + modified_sdp += "a=extmap:1 uri1\r\n"; + auto modified_offer = CreateSessionDescription(SdpType::kOffer, modified_sdp); + ASSERT_TRUE(pc->SetLocalDescription(std::move(modified_offer))); + + auto offer2 = + pc->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions()); + EXPECT_THAT(offer2->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(), + ElementsAre(Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"), + Field(&RtpExtension::uri, "uri4"), + Field(&RtpExtension::uri, "uri1"))); +} + +TEST_P(PeerConnectionHeaderExtensionTest, EnablingExtensionsAfterRemoteOffer) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::unique_ptr pc = + CreatePeerConnection(media_type, semantics); + std::string sdp = + "v=0\r\n" + "o=- 0 3 IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n" + "a=fingerprint:sha-256 " + "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:" + "AD:7E:77:43:2A:29:EC:93\r\n" + "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n" + "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n"; + if (media_type == cricket::MEDIA_TYPE_AUDIO) { + sdp += + "m=audio 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_audio_codec/8000\r\n"; + } else { + sdp += + "m=video 9 RTP/AVPF 111\r\n" + "a=rtpmap:111 fake_video_codec/90000\r\n"; + } + sdp += + "c=IN IP4 0.0.0.0\r\n" + "a=rtcp-mux\r\n" + "a=sendrecv\r\n" + "a=mid:audio\r\n" + "a=setup:actpass\r\n" + "a=extmap:5 uri1\r\n"; + auto offer = CreateSessionDescription(SdpType::kOffer, sdp); + pc->SetRemoteDescription(std::move(offer)); + + ASSERT_GT(pc->pc()->GetTransceivers().size(), 0u); + auto transceiver = pc->pc()->GetTransceivers()[0]; + auto modified_extensions = transceiver->GetHeaderExtensionsToNegotiate(); + modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv; + transceiver->SetHeaderExtensionsToNegotiate(modified_extensions); + + pc->CreateAnswerAndSetAsLocal( + PeerConnectionInterface::RTCOfferAnswerOptions()); + + auto session_description = pc->CreateOffer(); + auto extensions = session_description->description() + ->contents()[0] + .media_description() + ->rtp_header_extensions(); + EXPECT_THAT(extensions, ElementsAre(Field(&RtpExtension::uri, "uri1"), + Field(&RtpExtension::uri, "uri2"), + Field(&RtpExtension::uri, "uri3"), + Field(&RtpExtension::uri, "uri4"))); + // Check uri1's id still matches the remote id. + EXPECT_EQ(extensions[0].id, 5); +} + INSTANTIATE_TEST_SUITE_P( , PeerConnectionHeaderExtensionTest, diff --git a/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc b/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc index fc0448bcef77b..6e823c8934b72 100644 --- a/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_ice_unittest.cc @@ -62,8 +62,16 @@ #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/create_peerconnection_factory.h" #include "api/uma_metrics.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "pc/peer_connection_proxy.h" #include "pc/test/fake_audio_capture_module.h" #include "pc/test/mock_peer_connection_observers.h" @@ -150,7 +158,12 @@ class PeerConnectionIceBaseTest : public ::testing::Test { rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), rtc::scoped_refptr(FakeAudioCaptureModule::Create()), CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(), + std::make_unique>(), + std::make_unique>(), nullptr /* audio_mixer */, nullptr /* audio_processing */); } @@ -1417,9 +1430,14 @@ class PeerConnectionIceConfigTest : public ::testing::Test { pc_factory_ = CreatePeerConnectionFactory( rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), FakeAudioCaptureModule::Create(), CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory(), CreateBuiltinVideoEncoderFactory(), - CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + CreateBuiltinAudioDecoderFactory(), + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); } void CreatePeerConnection(const RTCConfiguration& config) { packet_socket_factory_.reset( diff --git a/third_party/libwebrtc/pc/peer_connection_integrationtest.cc b/third_party/libwebrtc/pc/peer_connection_integrationtest.cc index 812833000b5a2..07c5e0c0d3710 100644 --- a/third_party/libwebrtc/pc/peer_connection_integrationtest.cc +++ b/third_party/libwebrtc/pc/peer_connection_integrationtest.cc @@ -1831,6 +1831,10 @@ TEST_P(PeerConnectionIntegrationTest, EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, callee()->ice_connection_state(), kDefaultTimeout); + // Part of reporting the stats will occur on the network thread, so flush it + // before checking NumEvents. + SendTask(network_thread(), [] {}); + EXPECT_METRIC_EQ(1, webrtc::metrics::NumEvents( "WebRTC.PeerConnection.CandidatePairType_UDP", webrtc::kIceCandidatePairHostNameHostName)); @@ -1959,6 +1963,10 @@ TEST_P(PeerConnectionIntegrationIceStatesTest, MAYBE_VerifyBestConnection) { EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, callee()->ice_connection_state(), kDefaultTimeout); + // Part of reporting the stats will occur on the network thread, so flush it + // before checking NumEvents. + SendTask(network_thread(), [] {}); + // TODO(bugs.webrtc.org/9456): Fix it. const int num_best_ipv4 = webrtc::metrics::NumEvents( "WebRTC.PeerConnection.IPMetrics", webrtc::kBestConnections_IPv4); diff --git a/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc b/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc index afbfcea6bf130..3023be1493b04 100644 --- a/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_interface_unittest.cc @@ -38,8 +38,16 @@ #include "api/scoped_refptr.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/transport/field_trial_based_config.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/codec.h" #include "media/base/media_config.h" #include "media/base/media_engine.h" @@ -678,9 +686,17 @@ class PeerConnectionInterfaceBaseTest : public ::testing::Test { fake_audio_capture_module_), webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); ASSERT_TRUE(pc_factory_); } @@ -1389,9 +1405,17 @@ TEST_P(PeerConnectionInterfaceTest, rtc::Thread::Current(), fake_audio_capture_module_, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */)); + std::make_unique>(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */)); PeerConnectionDependencies pc_dependencies(&observer_); pc_dependencies.allocator = std::move(port_allocator); auto result = pc_factory_->CreatePeerConnectionOrError( @@ -1989,6 +2013,16 @@ TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannel) { EXPECT_FALSE(observer_.renegotiation_needed_); } +TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWhenClosed) { + RTCConfiguration rtc_config; + CreatePeerConnection(rtc_config); + pc_->Close(); + webrtc::DataChannelInit config; + auto ret = pc_->CreateDataChannelOrError("1", &config); + ASSERT_FALSE(ret.ok()); + EXPECT_EQ(ret.error().type(), RTCErrorType::INVALID_STATE); +} + // For backwards compatibility, we want people who "unset" maxRetransmits // and maxRetransmitTime by setting them to -1 to get what they want. TEST_P(PeerConnectionInterfaceTest, CreateSctpDataChannelWithMinusOne) { diff --git a/third_party/libwebrtc/pc/peer_connection_internal.h b/third_party/libwebrtc/pc/peer_connection_internal.h index debe830126bae..c91a44a1482a0 100644 --- a/third_party/libwebrtc/pc/peer_connection_internal.h +++ b/third_party/libwebrtc/pc/peer_connection_internal.h @@ -76,13 +76,7 @@ class PeerConnectionSdpMethods { virtual LegacyStatsCollector* legacy_stats() = 0; // Returns the observer. Will crash on CHECK if the observer is removed. virtual PeerConnectionObserver* Observer() const = 0; - // TODO(webrtc:11547): Remove `GetSctpSslRole` and require `GetSctpSslRole_n` - // instead. Currently `GetSctpSslRole` relied upon by `DataChannelController`. - // Once that path has been updated to use `GetSctpSslRole_n`, this method - // can be removed. - virtual bool GetSctpSslRole(rtc::SSLRole* role) = 0; - virtual absl::optional GetSctpSslRole_n( - absl::optional is_caller) = 0; + virtual absl::optional GetSctpSslRole_n() = 0; virtual PeerConnectionInterface::IceConnectionState ice_connection_state_internal() = 0; virtual void SetIceConnectionState( @@ -123,10 +117,16 @@ class PeerConnectionSdpMethods { // Returns true if SRTP (either using DTLS-SRTP or SDES) is required by // this session. virtual bool SrtpRequired() const = 0; - virtual bool SetupDataChannelTransport_n(const std::string& mid) = 0; - virtual void TeardownDataChannelTransport_n() = 0; - virtual void SetSctpDataMid(const std::string& mid) = 0; - virtual void ResetSctpDataMid() = 0; + // Configures the data channel transport on the network thread. + // The return value will be unset if an error occurs. If the setup succeeded + // the return value will be set and contain the name of the transport + // (empty string if a name isn't available). + virtual absl::optional SetupDataChannelTransport_n( + absl::string_view mid) = 0; + virtual void TeardownDataChannelTransport_n(RTCError error) = 0; + virtual void SetSctpDataInfo(absl::string_view mid, + absl::string_view transport_name) = 0; + virtual void ResetSctpDataInfo() = 0; virtual const FieldTrialsView& trials() const = 0; @@ -183,8 +183,11 @@ class PeerConnectionInternal : public PeerConnectionInterface, // Functions needed by DataChannelController virtual void NoteDataAddedEvent() {} // Handler for sctp data channel state changes. + // The `channel_id` is the same unique identifier as used in + // `DataChannelStats::internal_id and + // `RTCDataChannelStats::data_channel_identifier`. virtual void OnSctpDataChannelStateChanged( - DataChannelInterface* channel, + int channel_id, DataChannelInterface::DataState state) {} }; diff --git a/third_party/libwebrtc/pc/peer_connection_rampup_tests.cc b/third_party/libwebrtc/pc/peer_connection_rampup_tests.cc index 0fbbe7502fd99..34b61b4e14f97 100644 --- a/third_party/libwebrtc/pc/peer_connection_rampup_tests.cc +++ b/third_party/libwebrtc/pc/peer_connection_rampup_tests.cc @@ -29,8 +29,16 @@ #include "api/stats/rtcstats_objects.h" #include "api/test/metrics/global_metrics_logger_and_exporter.h" #include "api/test/metrics/metric.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "p2p/base/port_allocator.h" @@ -164,7 +172,12 @@ class PeerConnectionRampUpTest : public ::testing::Test { network_thread_.get(), worker_thread_.get(), rtc::Thread::Current(), rtc::scoped_refptr(FakeAudioCaptureModule::Create()), CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(), + std::make_unique>(), + std::make_unique>(), nullptr /* audio_mixer */, nullptr /* audio_processing */); } diff --git a/third_party/libwebrtc/pc/peer_connection_rtp_unittest.cc b/third_party/libwebrtc/pc/peer_connection_rtp_unittest.cc index e5861ea81536a..1ff48cd0a5220 100644 --- a/third_party/libwebrtc/pc/peer_connection_rtp_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_rtp_unittest.cc @@ -34,8 +34,16 @@ #include "api/scoped_refptr.h" #include "api/set_remote_description_observer_interface.h" #include "api/uma_metrics.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/stream_params.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -87,17 +95,25 @@ class PeerConnectionRtpBaseTest : public ::testing::Test { public: explicit PeerConnectionRtpBaseTest(SdpSemantics sdp_semantics) : sdp_semantics_(sdp_semantics), - pc_factory_( - CreatePeerConnectionFactory(rtc::Thread::Current(), - rtc::Thread::Current(), - rtc::Thread::Current(), - FakeAudioCaptureModule::Create(), - CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), - CreateBuiltinVideoDecoderFactory(), - nullptr /* audio_mixer */, - nullptr /* audio_processing */)) { + pc_factory_(CreatePeerConnectionFactory( + rtc::Thread::Current(), + rtc::Thread::Current(), + rtc::Thread::Current(), + FakeAudioCaptureModule::Create(), + CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory(), + std::make_unique< + VideoEncoderFactoryTemplate>(), + std::make_unique< + VideoDecoderFactoryTemplate>(), + nullptr /* audio_mixer */, + nullptr /* audio_processing */)) { webrtc::metrics::Reset(); } diff --git a/third_party/libwebrtc/pc/peer_connection_signaling_unittest.cc b/third_party/libwebrtc/pc/peer_connection_signaling_unittest.cc index 3ff890ab6a749..8ca59fc20c54c 100644 --- a/third_party/libwebrtc/pc/peer_connection_signaling_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_signaling_unittest.cc @@ -39,8 +39,16 @@ #include "api/scoped_refptr.h" #include "api/set_local_description_observer_interface.h" #include "api/set_remote_description_observer_interface.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/codec.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -134,7 +142,12 @@ class PeerConnectionSignalingBaseTest : public ::testing::Test { rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(), rtc::scoped_refptr(FakeAudioCaptureModule::Create()), CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), CreateBuiltinVideoDecoderFactory(), + std::make_unique>(), + std::make_unique>(), nullptr /* audio_mixer */, nullptr /* audio_processing */); } diff --git a/third_party/libwebrtc/pc/peer_connection_simulcast_unittest.cc b/third_party/libwebrtc/pc/peer_connection_simulcast_unittest.cc index ffa7ab6cca0f0..11a0fb121fed9 100644 --- a/third_party/libwebrtc/pc/peer_connection_simulcast_unittest.cc +++ b/third_party/libwebrtc/pc/peer_connection_simulcast_unittest.cc @@ -35,11 +35,18 @@ #include "api/rtp_transceiver_direction.h" #include "api/rtp_transceiver_interface.h" #include "api/scoped_refptr.h" -#include "api/stats/rtcstats_objects.h" #include "api/uma_metrics.h" #include "api/video/video_codec_constants.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/base/media_constants.h" #include "media/base/rid_description.h" #include "media/base/stream_params.h" @@ -52,15 +59,13 @@ #include "pc/simulcast_description.h" #include "pc/test/fake_audio_capture_module.h" #include "pc/test/mock_peer_connection_observers.h" -#include "pc/test/peer_connection_test_wrapper.h" +#include "pc/test/simulcast_layer_util.h" #include "rtc_base/checks.h" #include "rtc_base/gunit.h" -#include "rtc_base/physical_socket_server.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/thread.h" #include "rtc_base/unique_id_generator.h" #include "system_wrappers/include/metrics.h" -#include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" @@ -73,13 +78,10 @@ using ::testing::Field; using ::testing::IsEmpty; using ::testing::Le; using ::testing::Ne; -using ::testing::Optional; using ::testing::Pair; using ::testing::Property; using ::testing::SizeIs; using ::testing::StartsWith; -using ::testing::StrCaseEq; -using ::testing::StrEq; using cricket::MediaContentDescription; using cricket::RidDescription; @@ -102,21 +104,6 @@ std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982) namespace { -std::vector CreateLayers(const std::vector& rids, - const std::vector& active) { - RTC_DCHECK_EQ(rids.size(), active.size()); - std::vector result; - absl::c_transform(rids, active, std::back_inserter(result), - [](const std::string& rid, bool is_active) { - return SimulcastLayer(rid, !is_active); - }); - return result; -} -std::vector CreateLayers(const std::vector& rids, - bool active) { - return CreateLayers(rids, std::vector(rids.size(), active)); -} - #if RTC_METRICS_ENABLED std::vector CreateLayers(int num_layers, bool active) { rtc::UniqueStringGenerator rid_generator; @@ -124,70 +111,36 @@ std::vector CreateLayers(int num_layers, bool active) { for (int i = 0; i < num_layers; ++i) { rids.push_back(rid_generator.GenerateString()); } - return CreateLayers(rids, active); + return webrtc::CreateLayers(rids, active); } #endif -// RTX, RED and FEC are reliability mechanisms used in combinations with other -// codecs, but are not themselves a specific codec. Typically you don't want to -// filter these out of the list of codec preferences. -bool IsReliabilityMechanism(const webrtc::RtpCodecCapability& codec) { - return absl::EqualsIgnoreCase(codec.name, cricket::kRtxCodecName) || - absl::EqualsIgnoreCase(codec.name, cricket::kRedCodecName) || - absl::EqualsIgnoreCase(codec.name, cricket::kUlpfecCodecName); -} - -std::string GetCurrentCodecMimeType( - rtc::scoped_refptr report, - const webrtc::RTCOutboundRtpStreamStats& outbound_rtp) { - return outbound_rtp.codec_id.is_defined() - ? *report->GetAs(*outbound_rtp.codec_id) - ->mime_type - : ""; -} - -struct RidAndResolution { - std::string rid; - uint32_t width; - uint32_t height; -}; - -const webrtc::RTCOutboundRtpStreamStats* FindOutboundRtpByRid( - const std::vector& outbound_rtps, - const absl::string_view& rid) { - for (const auto* outbound_rtp : outbound_rtps) { - if (outbound_rtp->rid.is_defined() && *outbound_rtp->rid == rid) { - return outbound_rtp; - } - } - return nullptr; -} - } // namespace namespace webrtc { -constexpr TimeDelta kDefaultTimeout = TimeDelta::Seconds(5); - -// Only used by tests disabled under ASAN, avoids unsued variable compile error. -#if !defined(ADDRESS_SANITIZER) -constexpr TimeDelta kLongTimeoutForRampingUp = TimeDelta::Seconds(30); -#endif // !defined(ADDRESS_SANITIZER) - class PeerConnectionSimulcastTests : public ::testing::Test { public: PeerConnectionSimulcastTests() - : pc_factory_( - CreatePeerConnectionFactory(rtc::Thread::Current(), - rtc::Thread::Current(), - rtc::Thread::Current(), - FakeAudioCaptureModule::Create(), - CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), - CreateBuiltinVideoDecoderFactory(), - nullptr, - nullptr)) {} + : pc_factory_(CreatePeerConnectionFactory( + rtc::Thread::Current(), + rtc::Thread::Current(), + rtc::Thread::Current(), + FakeAudioCaptureModule::Create(), + CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory(), + std::make_unique< + VideoEncoderFactoryTemplate>(), + std::make_unique< + VideoDecoderFactoryTemplate>(), + nullptr, + nullptr)) {} rtc::scoped_refptr CreatePeerConnection( MockPeerConnectionObserver* observer) { @@ -226,18 +179,6 @@ class PeerConnectionSimulcastTests : public ::testing::Test { EXPECT_TRUE(local->SetRemoteDescription(std::move(answer), &err)) << err; } - RtpTransceiverInit CreateTransceiverInit( - const std::vector& layers) { - RtpTransceiverInit init; - for (const SimulcastLayer& layer : layers) { - RtpEncodingParameters encoding; - encoding.rid = layer.rid; - encoding.active = !layer.is_paused; - init.send_encodings.push_back(encoding); - } - return init; - } - rtc::scoped_refptr AddTransceiver( PeerConnectionWrapper* pc, const std::vector& layers, @@ -246,13 +187,6 @@ class PeerConnectionSimulcastTests : public ::testing::Test { return pc->AddTransceiver(media_type, init); } - SimulcastDescription RemoveSimulcast(SessionDescriptionInterface* sd) { - auto mcd = sd->description()->contents()[0].media_description(); - auto result = mcd->simulcast_description(); - mcd->set_simulcast_description(SimulcastDescription()); - return result; - } - void AddRequestToReceiveSimulcast(const std::vector& layers, SessionDescriptionInterface* sd) { auto mcd = sd->description()->contents()[0].media_description(); @@ -686,7 +620,7 @@ TEST_F(PeerConnectionSimulcastTests, SimulcastSldModificationRejected) { TEST_F(PeerConnectionSimulcastMetricsTests, NoSimulcastUsageIsLogged) { auto local = CreatePeerConnectionWrapper(); auto remote = CreatePeerConnectionWrapper(); - auto layers = CreateLayers(0, true); + auto layers = ::CreateLayers(0, true); AddTransceiver(local.get(), layers); ExchangeOfferAnswer(local.get(), remote.get(), layers); @@ -700,7 +634,7 @@ TEST_F(PeerConnectionSimulcastMetricsTests, NoSimulcastUsageIsLogged) { TEST_F(PeerConnectionSimulcastMetricsTests, SpecComplianceIsLogged) { auto local = CreatePeerConnectionWrapper(); auto remote = CreatePeerConnectionWrapper(); - auto layers = CreateLayers(3, true); + auto layers = ::CreateLayers(3, true); AddTransceiver(local.get(), layers); ExchangeOfferAnswer(local.get(), remote.get(), layers); @@ -720,7 +654,7 @@ TEST_F(PeerConnectionSimulcastMetricsTests, SpecComplianceIsLogged) { TEST_F(PeerConnectionSimulcastMetricsTests, IncomingSimulcastIsLogged) { auto local = CreatePeerConnectionWrapper(); auto remote = CreatePeerConnectionWrapper(); - auto layers = CreateLayers(3, true); + auto layers = ::CreateLayers(3, true); AddTransceiver(local.get(), layers); auto offer = local->CreateOfferAndSetAsLocal(); EXPECT_THAT(LocalDescriptionSamples(), @@ -769,7 +703,7 @@ TEST_F(PeerConnectionSimulcastMetricsTests, RejectedSimulcastIsLogged) { TEST_F(PeerConnectionSimulcastMetricsTests, LegacySimulcastIsLogged) { auto local = CreatePeerConnectionWrapper(); auto remote = CreatePeerConnectionWrapper(); - auto layers = CreateLayers(0, true); + auto layers = ::CreateLayers(0, true); AddTransceiver(local.get(), layers); auto offer = local->CreateOffer(); // Munge the SDP to set up legacy simulcast. @@ -838,7 +772,7 @@ const int kMaxLayersInMetricsTest = 8; TEST_P(PeerConnectionSimulcastMetricsTests, NumberOfSendEncodingsIsLogged) { auto local = CreatePeerConnectionWrapper(); auto num_layers = GetParam(); - auto layers = CreateLayers(num_layers, true); + auto layers = ::CreateLayers(num_layers, true); AddTransceiver(local.get(), layers); EXPECT_EQ(1, metrics::NumSamples( "WebRTC.PeerConnection.Simulcast.NumberOfSendEncodings")); @@ -852,851 +786,4 @@ INSTANTIATE_TEST_SUITE_P(NumberOfSendEncodings, ::testing::Range(0, kMaxLayersInMetricsTest)); #endif -// Inherits some helper methods from PeerConnectionSimulcastTests but -// uses real threads and PeerConnectionTestWrapper to create fake media streams -// with flowing media and establish connections. -// TODO(https://crbug.com/webrtc/14884): Move these integration tests into a -// separate file and rename them to PeerConnectionEncodingIntegrationTests. -class PeerConnectionSimulcastWithMediaFlowTests - : public PeerConnectionSimulcastTests { - public: - PeerConnectionSimulcastWithMediaFlowTests() - : background_thread_(std::make_unique(&pss_)) { - RTC_CHECK(background_thread_->Start()); - } - - rtc::scoped_refptr CreatePc() { - auto pc_wrapper = rtc::make_ref_counted( - "pc", &pss_, background_thread_.get(), background_thread_.get()); - pc_wrapper->CreatePc({}, webrtc::CreateOpusAudioEncoderFactory(), - webrtc::CreateOpusAudioDecoderFactory()); - return pc_wrapper; - } - - rtc::scoped_refptr AddTransceiverWithSimulcastLayers( - rtc::scoped_refptr local, - rtc::scoped_refptr remote, - std::vector init_layers) { - rtc::scoped_refptr stream = - local->GetUserMedia( - /*audio=*/false, cricket::AudioOptions(), /*video=*/true, - {.width = 1280, .height = 720}); - rtc::scoped_refptr track = stream->GetVideoTracks()[0]; - - RTCErrorOr> - transceiver_or_error = local->pc()->AddTransceiver( - track, CreateTransceiverInit(init_layers)); - EXPECT_TRUE(transceiver_or_error.ok()); - return transceiver_or_error.value(); - } - - bool HasSenderVideoCodecCapability( - rtc::scoped_refptr pc_wrapper, - absl::string_view codec_name) { - std::vector codecs = - pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) - .codecs; - return std::find_if(codecs.begin(), codecs.end(), - [&codec_name](const RtpCodecCapability& codec) { - return absl::EqualsIgnoreCase(codec.name, codec_name); - }) != codecs.end(); - } - - std::vector GetCapabilitiesAndRestrictToCodec( - rtc::scoped_refptr pc_wrapper, - absl::string_view codec_name) { - std::vector codecs = - pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) - .codecs; - codecs.erase(std::remove_if(codecs.begin(), codecs.end(), - [&codec_name](const RtpCodecCapability& codec) { - return !IsReliabilityMechanism(codec) && - !absl::EqualsIgnoreCase(codec.name, - codec_name); - }), - codecs.end()); - RTC_DCHECK(std::find_if(codecs.begin(), codecs.end(), - [&codec_name](const RtpCodecCapability& codec) { - return absl::EqualsIgnoreCase(codec.name, - codec_name); - }) != codecs.end()); - return codecs; - } - - void ExchangeIceCandidates( - rtc::scoped_refptr local_pc_wrapper, - rtc::scoped_refptr remote_pc_wrapper) { - local_pc_wrapper->SignalOnIceCandidateReady.connect( - remote_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate); - remote_pc_wrapper->SignalOnIceCandidateReady.connect( - local_pc_wrapper.get(), &PeerConnectionTestWrapper::AddIceCandidate); - } - - void NegotiateWithSimulcastTweaks( - rtc::scoped_refptr local_pc_wrapper, - rtc::scoped_refptr remote_pc_wrapper, - std::vector init_layers) { - // Create and set offer for `local_pc_wrapper`. - std::unique_ptr offer = - CreateOffer(local_pc_wrapper); - rtc::scoped_refptr p1 = - SetLocalDescription(local_pc_wrapper, offer.get()); - // Modify the offer before handoff because `remote_pc_wrapper` only supports - // receiving singlecast. - SimulcastDescription simulcast_description = RemoveSimulcast(offer.get()); - rtc::scoped_refptr p2 = - SetRemoteDescription(remote_pc_wrapper, offer.get()); - EXPECT_TRUE(Await({p1, p2})); - - // Create and set answer for `remote_pc_wrapper`. - std::unique_ptr answer = - CreateAnswer(remote_pc_wrapper); - p1 = SetLocalDescription(remote_pc_wrapper, answer.get()); - // Modify the answer before handoff because `local_pc_wrapper` should still - // send simulcast. - cricket::MediaContentDescription* mcd_answer = - answer->description()->contents()[0].media_description(); - mcd_answer->mutable_streams().clear(); - std::vector simulcast_layers = - simulcast_description.send_layers().GetAllLayers(); - cricket::SimulcastLayerList& receive_layers = - mcd_answer->simulcast_description().receive_layers(); - for (const auto& layer : simulcast_layers) { - receive_layers.AddLayer(layer); - } - p2 = SetRemoteDescription(local_pc_wrapper, answer.get()); - EXPECT_TRUE(Await({p1, p2})); - } - - rtc::scoped_refptr GetStats( - rtc::scoped_refptr pc_wrapper) { - auto callback = rtc::make_ref_counted(); - pc_wrapper->pc()->GetStats(callback.get()); - EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout.ms()); - return callback->report(); - } - - bool HasOutboundRtpBytesSent( - rtc::scoped_refptr pc_wrapper, - size_t num_layers) { - return HasOutboundRtpBytesSent(pc_wrapper, num_layers, num_layers); - } - - bool HasOutboundRtpBytesSent( - rtc::scoped_refptr pc_wrapper, - size_t num_layers, - size_t num_active_layers) { - rtc::scoped_refptr report = GetStats(pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - if (outbound_rtps.size() != num_layers) { - return false; - } - size_t num_sending_layers = 0; - for (const auto* outbound_rtp : outbound_rtps) { - if (outbound_rtp->bytes_sent.is_defined() && - *outbound_rtp->bytes_sent > 0u) { - ++num_sending_layers; - } - } - return num_sending_layers == num_active_layers; - } - - bool HasOutboundRtpWithRidAndScalabilityMode( - rtc::scoped_refptr pc_wrapper, - absl::string_view rid, - absl::string_view expected_scalability_mode, - uint32_t frame_height) { - rtc::scoped_refptr report = GetStats(pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - auto* outbound_rtp = FindOutboundRtpByRid(outbound_rtps, rid); - if (!outbound_rtp || !outbound_rtp->scalability_mode.is_defined() || - *outbound_rtp->scalability_mode != expected_scalability_mode) { - return false; - } - if (outbound_rtp->frame_height.is_defined()) { - RTC_LOG(LS_INFO) << "Waiting for target resolution (" << frame_height - << "p). Currently at " << *outbound_rtp->frame_height - << "p..."; - } else { - RTC_LOG(LS_INFO) - << "Waiting for target resolution. No frames encoded yet..."; - } - if (!outbound_rtp->frame_height.is_defined() || - *outbound_rtp->frame_height != frame_height) { - // Sleep to avoid log spam when this is used in EXPECT_TRUE_WAIT(). - rtc::Thread::Current()->SleepMs(1000); - return false; - } - return true; - } - - bool OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - rtc::scoped_refptr pc_wrapper, - std::vector resolutions) { - rtc::scoped_refptr report = GetStats(pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - for (const RidAndResolution& resolution : resolutions) { - const RTCOutboundRtpStreamStats* outbound_rtp = nullptr; - if (!resolution.rid.empty()) { - outbound_rtp = FindOutboundRtpByRid(outbound_rtps, resolution.rid); - } else if (outbound_rtps.size() == 1u) { - outbound_rtp = outbound_rtps[0]; - } - if (!outbound_rtp || !outbound_rtp->frame_width.is_defined() || - !outbound_rtp->frame_height.is_defined()) { - // RTP not found by rid or has not encoded a frame yet. - RTC_LOG(LS_ERROR) << "rid=" << resolution.rid << " does not have " - << "resolution metrics"; - return false; - } - if (*outbound_rtp->frame_width > resolution.width || - *outbound_rtp->frame_height > resolution.height) { - RTC_LOG(LS_ERROR) << "rid=" << resolution.rid << " is " - << *outbound_rtp->frame_width << "x" - << *outbound_rtp->frame_height - << ", this is greater than the " - << "expected " << resolution.width << "x" - << resolution.height; - return false; - } - } - return true; - } - - protected: - std::unique_ptr CreateOffer( - rtc::scoped_refptr pc_wrapper) { - auto observer = - rtc::make_ref_counted(); - pc_wrapper->pc()->CreateOffer(observer.get(), {}); - EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); - return observer->MoveDescription(); - } - - std::unique_ptr CreateAnswer( - rtc::scoped_refptr pc_wrapper) { - auto observer = - rtc::make_ref_counted(); - pc_wrapper->pc()->CreateAnswer(observer.get(), {}); - EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); - return observer->MoveDescription(); - } - - rtc::scoped_refptr SetLocalDescription( - rtc::scoped_refptr pc_wrapper, - SessionDescriptionInterface* sdp) { - auto observer = rtc::make_ref_counted(); - pc_wrapper->pc()->SetLocalDescription( - observer.get(), CloneSessionDescription(sdp).release()); - return observer; - } - - rtc::scoped_refptr SetRemoteDescription( - rtc::scoped_refptr pc_wrapper, - SessionDescriptionInterface* sdp) { - auto observer = rtc::make_ref_counted(); - pc_wrapper->pc()->SetRemoteDescription( - observer.get(), CloneSessionDescription(sdp).release()); - return observer; - } - - // To avoid ICE candidates arriving before the remote endpoint has received - // the offer it is important to SetLocalDescription() and - // SetRemoteDescription() are kicked off without awaiting in-between. This - // helper is used to await multiple observers. - bool Await(std::vector> - observers) { - for (auto& observer : observers) { - EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout.ms()); - if (!observer->result()) { - return false; - } - } - return true; - } - - rtc::PhysicalSocketServer pss_; - std::unique_ptr background_thread_; -}; - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingOneEncodings_VP8_DefaultsToL1T1) { - 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); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); - transceiver->SetCodecPreferences(codecs); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), - kDefaultTimeout.ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"", 1280, 720}})); - // Verify codec and scalability mode. - 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("L1T1")); -} - -// TODO(https://crbug.com/webrtc/15018): Investigate heap-use-after free during -// shutdown of the test that is flakily happening on bots. It's not only -// happening on ASAN, but it is rare enough on non-ASAN that we don't have to -// disable everywhere. -#if !defined(ADDRESS_SANITIZER) - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_VP8_Simulcast) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); - transceiver->SetCodecPreferences(codecs); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing on all three layers. - // Ramp up time is needed before all three layers are sending. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u), - kLongTimeoutForRampingUp.ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"f", 320, 180}, {"h", 640, 360}, {"q", 1280, 720}})); - // Verify codec and scalability mode. - rtc::scoped_refptr report = GetStats(local_pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - ASSERT_THAT(outbound_rtps, SizeIs(3u)); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), - StrCaseEq("video/VP8")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]), - StrCaseEq("video/VP8")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]), - StrCaseEq("video/VP8")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); -} - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingOneEncoding_VP8_RejectsSVCWhenNotPossibleAndDefaultsToL1T1) { - 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 codecs restricts what SetParameters() will accept or reject. - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); - transceiver->SetCodecPreferences(codecs); - // 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(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - EXPECT_FALSE(sender->SetParameters(parameters).ok()); - // `scalability_mode` remains unset because SetParameters() failed. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing. - EXPECT_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("L1T1")); - // 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(absl::nullopt)); -} - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingOneEncoding_VP8_FallbackFromSVCResultsInL1T2) { - 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); - // Verify test assumption that VP8 is first in the list, but don't modify the - // codec preferences because we want the sender to think SVC is a possibility. - std::vector codecs = - local_pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) - .codecs; - EXPECT_THAT(codecs[0].name, StrCaseEq("VP8")); - // Attempt SVC (L3T3_KEY), which is not possible with VP8, but the sender does - // not yet know which codec we'll use so the parameters will be accepted. - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - EXPECT_TRUE(sender->SetParameters(parameters).ok()); - // Verify fallback has not happened yet. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L3T3_KEY"))); - - // Negotiate, this results in VP8 being picked and fallback happening. - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - // `scalaiblity_mode` is assigned the fallback value "L1T2" which is different - // than the default of absl::nullopt. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L1T2"))); - - // Wait until media is flowing, no significant time needed because we only - // have one layer. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), - kDefaultTimeout.ms()); - // GetStats() confirms "L1T2" is used which is different than the "L1T1" - // default or the "L3T3_KEY" that was attempted. - 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")); -} - -#if defined(WEBRTC_USE_H264) - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_H264_Simulcast) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "H264"); - transceiver->SetCodecPreferences(codecs); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing on all three layers. - // Ramp up time is needed before all three layers are sending. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u), - kLongTimeoutForRampingUp.ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"f", 320, 180}, {"h", 640, 360}, {"q", 1280, 720}})); - // Verify codec and scalability mode. - rtc::scoped_refptr report = GetStats(local_pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - ASSERT_THAT(outbound_rtps, SizeIs(3u)); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), - StrCaseEq("video/H264")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]), - StrCaseEq("video/H264")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]), - StrCaseEq("video/H264")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); -} - -#endif // defined(WEBRTC_USE_H264) - -// The legacy SVC path is triggered when VP9 us used, but `scalability_mode` has -// not been specified. -// TODO(https://crbug.com/webrtc/14889): When legacy VP9 SVC path has been -// deprecated and removed, update this test to assert that simulcast is used -// (i.e. VP9 is not treated differently than VP8). -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_VP9_LegacySVC) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); - transceiver->SetCodecPreferences(codecs); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing. We only expect a single RTP stream. - // We expect to see bytes flowing almost immediately on the lowest layer. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), - kDefaultTimeout.ms()); - // Wait until scalability mode is reported and expected resolution reached. - // Ramp up time may be significant. - EXPECT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( - local_pc_wrapper, "f", "L3T3_KEY", 720), - (2 * kLongTimeoutForRampingUp).ms()); - - // Despite SVC being used on a single RTP stream, GetParameters() returns the - // three encodings that we configured earlier (this is not spec-compliant but - // it is how legacy SVC behaves). - rtc::scoped_refptr sender = transceiver->sender(); - std::vector encodings = - sender->GetParameters().encodings; - ASSERT_EQ(encodings.size(), 3u); - // When legacy SVC is used, `scalability_mode` is not specified. - EXPECT_FALSE(encodings[0].scalability_mode.has_value()); - EXPECT_FALSE(encodings[1].scalability_mode.has_value()); - EXPECT_FALSE(encodings[2].scalability_mode.has_value()); -} - -// The spec-compliant way to configure SVC for a single stream. The expected -// outcome is the same as for the legacy SVC case except that we only have one -// encoding in GetParameters(). -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingOneEncoding_VP9_StandardSVC) { - 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); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); - transceiver->SetCodecPreferences(codecs); - // Configure SVC, a.k.a. "L3T3_KEY". - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - EXPECT_TRUE(sender->SetParameters(parameters).ok()); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing. We only expect a single RTP stream. - // We expect to see bytes flowing almost immediately on the lowest layer. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), - kDefaultTimeout.ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"", 1280, 720}})); - // Verify codec and scalability mode. - 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/VP9")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L3T3_KEY")); - - // GetParameters() is consistent with what we asked for and got. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L3T3_KEY"))); -} - -// The {active,inactive,inactive} case is technically simulcast but since we -// only have one active stream, we're able to do SVC (multiple spatial layers -// is not supported if multiple encodings are active). The expected outcome is -// the same as above except we end up with two inactive RTP streams which are -// observable in GetStats(). -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_VP9_StandardSVC) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); - transceiver->SetCodecPreferences(codecs); - // Configure SVC, a.k.a. "L3T3_KEY". - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - parameters.encodings[0].scale_resolution_down_by = 1; - parameters.encodings[1].active = false; - parameters.encodings[2].active = false; - EXPECT_TRUE(sender->SetParameters(parameters).ok()); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Since the standard API is configuring simulcast we get three outbound-rtps, - // but only one is active. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u, 1u), - kDefaultTimeout.ms()); - // Wait until scalability mode is reported and expected resolution reached. - // Ramp up time is significant. - EXPECT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( - local_pc_wrapper, "f", "L3T3_KEY", 720), - (2 * kLongTimeoutForRampingUp).ms()); - - // GetParameters() is consistent with what we asked for and got. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L3T3_KEY"))); - EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value()); - EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value()); -} - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_VP9_Simulcast) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); - transceiver->SetCodecPreferences(codecs); - - // Opt-in to spec-compliant simulcast by explicitly setting the - // `scalability_mode` and `scale_resolution_down_by` parameters. - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - parameters.encodings[0].scalability_mode = "L1T3"; - parameters.encodings[0].scale_resolution_down_by = 4; - parameters.encodings[1].scalability_mode = "L1T3"; - parameters.encodings[1].scale_resolution_down_by = 2; - parameters.encodings[2].scalability_mode = "L1T3"; - parameters.encodings[2].scale_resolution_down_by = 1; - sender->SetParameters(parameters); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // GetParameters() does not report any fallback. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L1T3"))); - EXPECT_THAT(parameters.encodings[1].scalability_mode, - Optional(std::string("L1T3"))); - EXPECT_THAT(parameters.encodings[2].scalability_mode, - Optional(std::string("L1T3"))); - - // Wait until media is flowing on all three layers. - // Ramp up time is needed before all three layers are sending. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u), - kLongTimeoutForRampingUp.ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"f", 320, 180}, {"h", 640, 360}, {"q", 1280, 720}})); - // Verify codec and scalability mode. - rtc::scoped_refptr report = GetStats(local_pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - ASSERT_THAT(outbound_rtps, SizeIs(3u)); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), - StrCaseEq("video/VP9")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]), - StrCaseEq("video/VP9")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]), - StrCaseEq("video/VP9")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); -} - -// Exercise common path where `scalability_mode` is not specified until after -// negotiation, requring us to recreate the stream when the number of streams -// changes from 1 (legacy SVC) to 3 (standard simulcast). -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_VP9_FromLegacyToSingleActiveWithScalability) { - 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", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); - transceiver->SetCodecPreferences(codecs); - - // The original negotiation triggers legacy SVC because we didn't specify - // any scalability mode. - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Switch to the standard mode. Despite only having a single active stream in - // both cases, this internally reconfigures from 1 stream to 3 streams. - // Test coverage for https://crbug.com/webrtc/15016. - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - parameters.encodings[0].active = true; - parameters.encodings[0].scalability_mode = "L2T2_KEY"; - parameters.encodings[0].scale_resolution_down_by = 2.0; - parameters.encodings[1].active = false; - parameters.encodings[1].scalability_mode = absl::nullopt; - parameters.encodings[2].active = false; - parameters.encodings[2].scalability_mode = absl::nullopt; - sender->SetParameters(parameters); - - // Since the standard API is configuring simulcast we get three outbound-rtps, - // but only one is active. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u, 1u), - kDefaultTimeout.ms()); - // Wait until scalability mode is reported and expected resolution reached. - // Ramp up time may be significant. - EXPECT_TRUE_WAIT(HasOutboundRtpWithRidAndScalabilityMode( - local_pc_wrapper, "f", "L2T2_KEY", 720 / 2), - (2 * kLongTimeoutForRampingUp).ms()); - - // GetParameters() does not report any fallback. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L2T2_KEY"))); - EXPECT_FALSE(parameters.encodings[1].scalability_mode.has_value()); - EXPECT_FALSE(parameters.encodings[2].scalability_mode.has_value()); -} - -TEST_F(PeerConnectionSimulcastWithMediaFlowTests, - SendingThreeEncodings_AV1_Simulcast) { - rtc::scoped_refptr local_pc_wrapper = CreatePc(); - // TODO(https://crbug.com/webrtc/15011): Expand testing support for AV1 or - // allow compile time checks so that gates like this isn't needed at runtime. - if (!HasSenderVideoCodecCapability(local_pc_wrapper, "AV1")) { - RTC_LOG(LS_WARNING) << "\n***\nAV1 is not available, skipping test.\n***"; - return; - } - rtc::scoped_refptr remote_pc_wrapper = CreatePc(); - ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper); - - std::vector layers = - CreateLayers({"f", "h", "q"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "AV1"); - transceiver->SetCodecPreferences(codecs); - - // Opt-in to spec-compliant simulcast by explicitly setting the - // `scalability_mode`. - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - parameters.encodings[0].scalability_mode = "L1T3"; - parameters.encodings[0].scale_resolution_down_by = 4; - parameters.encodings[1].scalability_mode = "L1T3"; - parameters.encodings[1].scale_resolution_down_by = 2; - parameters.encodings[2].scalability_mode = "L1T3"; - parameters.encodings[2].scale_resolution_down_by = 1; - sender->SetParameters(parameters); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper, layers); - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // GetParameters() does not report any fallback. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 3u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, - Optional(std::string("L1T3"))); - EXPECT_THAT(parameters.encodings[1].scalability_mode, - Optional(std::string("L1T3"))); - EXPECT_THAT(parameters.encodings[2].scalability_mode, - Optional(std::string("L1T3"))); - - // Wait until media is flowing on all three layers. - // Ramp up time is needed before all three layers are sending. - // - // This test is given 2X timeout because AV1 simulcast ramp-up time is - // terrible compared to other codecs. - // TODO(https://crbug.com/webrtc/15006): Improve the ramp-up time and stop - // giving this test extra long timeout. - EXPECT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 3u), - (2 * kLongTimeoutForRampingUp).ms()); - EXPECT_TRUE(OutboundRtpResolutionsAreLessThanOrEqualToExpectations( - local_pc_wrapper, {{"f", 320, 180}, {"h", 640, 360}, {"q", 1280, 720}})); - // Verify codec and scalability mode. - rtc::scoped_refptr report = GetStats(local_pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - ASSERT_THAT(outbound_rtps, SizeIs(3u)); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), - StrCaseEq("video/AV1")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[1]), - StrCaseEq("video/AV1")); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[2]), - StrCaseEq("video/AV1")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[1]->scalability_mode, StrEq("L1T3")); - EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); -} - -#endif // !defined(ADDRESS_SANITIZER) - } // namespace webrtc diff --git a/third_party/libwebrtc/pc/proxy.h b/third_party/libwebrtc/pc/proxy.h index 2be115fdf3967..b0782bb1eabe3 100644 --- a/third_party/libwebrtc/pc/proxy.h +++ b/third_party/libwebrtc/pc/proxy.h @@ -449,7 +449,31 @@ class ConstMethodCall { TRACE_BOILERPLATE(method); \ return c_->method(); \ } +// Allows a custom implementation of a method where the otherwise proxied +// implementation can do a more efficient, yet thread-safe, job than the proxy +// can do by default or when more flexibility is needed than can be provided +// by a proxy. +// Note that calls to these methods should be expected to be made from unknown +// threads. +#define BYPASS_PROXY_METHOD0(r, method) \ + r method() override { \ + TRACE_BOILERPLATE(method); \ + return c_->method(); \ + } + +// The 1 argument version of `BYPASS_PROXY_METHOD0`. +#define BYPASS_PROXY_METHOD1(r, method, t1) \ + r method(t1 a1) override { \ + TRACE_BOILERPLATE(method); \ + return c_->method(std::move(a1)); \ + } +// The 2 argument version of `BYPASS_PROXY_METHOD0`. +#define BYPASS_PROXY_METHOD2(r, method, t1, t2) \ + r method(t1 a1, t2 a2) override { \ + TRACE_BOILERPLATE(method); \ + return c_->method(std::move(a1), std::move(a2)); \ + } } // namespace webrtc #endif // PC_PROXY_H_ diff --git a/third_party/libwebrtc/pc/rtc_stats_collector.cc b/third_party/libwebrtc/pc/rtc_stats_collector.cc index 1d8cf3ca6d9e0..9b9f5ba1fdba7 100644 --- a/third_party/libwebrtc/pc/rtc_stats_collector.cc +++ b/third_party/libwebrtc/pc/rtc_stats_collector.cc @@ -416,11 +416,11 @@ void SetInboundRTPStreamStatsFromMediaReceiverInfo( RTC_DCHECK(inbound_stats); inbound_stats->ssrc = media_receiver_info.ssrc(); inbound_stats->packets_received = - static_cast(media_receiver_info.packets_rcvd); + static_cast(media_receiver_info.packets_received); inbound_stats->bytes_received = - static_cast(media_receiver_info.payload_bytes_rcvd); - inbound_stats->header_bytes_received = - static_cast(media_receiver_info.header_and_padding_bytes_rcvd); + static_cast(media_receiver_info.payload_bytes_received); + inbound_stats->header_bytes_received = static_cast( + media_receiver_info.header_and_padding_bytes_received); inbound_stats->packets_lost = static_cast(media_receiver_info.packets_lost); inbound_stats->jitter_buffer_delay = @@ -459,7 +459,7 @@ std::unique_ptr CreateInboundAudioStreamStats( inbound_audio->kind = "audio"; if (voice_receiver_info.codec_payload_type.has_value()) { auto codec_param_it = voice_media_info.receive_codecs.find( - voice_receiver_info.codec_payload_type.value()); + *voice_receiver_info.codec_payload_type); RTC_DCHECK(codec_param_it != voice_media_info.receive_codecs.end()); if (codec_param_it != voice_media_info.receive_codecs.end()) { inbound_audio->codec_id = GetCodecIdAndMaybeCreateCodecStats( @@ -551,8 +551,7 @@ CreateRemoteOutboundAudioStreamStats( auto stats = std::make_unique( /*id=*/RTCRemoteOutboundRTPStreamStatsIDFromSSRC( cricket::MEDIA_TYPE_AUDIO, voice_receiver_info.ssrc()), - Timestamp::Millis( - voice_receiver_info.last_sender_report_timestamp_ms.value())); + Timestamp::Millis(*voice_receiver_info.last_sender_report_timestamp_ms)); // Populate. // - RTCRtpStreamStats. @@ -567,10 +566,12 @@ CreateRemoteOutboundAudioStreamStats( stats->bytes_sent = voice_receiver_info.sender_reports_bytes_sent; // - RTCRemoteOutboundRtpStreamStats. stats->local_id = inbound_audio_stats.id(); + // last_sender_report_remote_timestamp_ms is set together with + // last_sender_report_timestamp_ms. RTC_DCHECK( voice_receiver_info.last_sender_report_remote_timestamp_ms.has_value()); stats->remote_timestamp = static_cast( - voice_receiver_info.last_sender_report_remote_timestamp_ms.value()); + *voice_receiver_info.last_sender_report_remote_timestamp_ms); stats->reports_sent = voice_receiver_info.sender_reports_reports_count; if (voice_receiver_info.round_trip_time.has_value()) { stats->round_trip_time = @@ -604,7 +605,7 @@ CreateInboundRTPStreamStatsFromVideoReceiverInfo( inbound_video->kind = "video"; if (video_receiver_info.codec_payload_type.has_value()) { auto codec_param_it = video_media_info.receive_codecs.find( - video_receiver_info.codec_payload_type.value()); + *video_receiver_info.codec_payload_type); RTC_DCHECK(codec_param_it != video_media_info.receive_codecs.end()); if (codec_param_it != video_media_info.receive_codecs.end()) { inbound_video->codec_id = GetCodecIdAndMaybeCreateCodecStats( @@ -682,7 +683,7 @@ CreateInboundRTPStreamStatsFromVideoReceiverInfo( } if (video_receiver_info.power_efficient_decoder.has_value()) { inbound_video->power_efficient_decoder = - video_receiver_info.power_efficient_decoder.value(); + *video_receiver_info.power_efficient_decoder; } return inbound_video; } @@ -706,7 +707,7 @@ void SetOutboundRTPStreamStatsFromMediaSenderInfo( static_cast(media_sender_info.header_and_padding_bytes_sent); outbound_stats->retransmitted_bytes_sent = media_sender_info.retransmitted_bytes_sent; - outbound_stats->nack_count = media_sender_info.nacks_rcvd; + outbound_stats->nack_count = media_sender_info.nacks_received; if (media_sender_info.active.has_value()) { outbound_stats->active = *media_sender_info.active; } @@ -736,7 +737,7 @@ CreateOutboundRTPStreamStatsFromVoiceSenderInfo( } if (voice_sender_info.codec_payload_type.has_value()) { auto codec_param_it = voice_media_info.send_codecs.find( - voice_sender_info.codec_payload_type.value()); + *voice_sender_info.codec_payload_type); RTC_DCHECK(codec_param_it != voice_media_info.send_codecs.end()); if (codec_param_it != voice_media_info.send_codecs.end()) { outbound_audio->codec_id = GetCodecIdAndMaybeCreateCodecStats( @@ -769,7 +770,7 @@ CreateOutboundRTPStreamStatsFromVideoSenderInfo( outbound_video->kind = "video"; if (video_sender_info.codec_payload_type.has_value()) { auto codec_param_it = video_media_info.send_codecs.find( - video_sender_info.codec_payload_type.value()); + *video_sender_info.codec_payload_type); RTC_DCHECK(codec_param_it != video_media_info.send_codecs.end()); if (codec_param_it != video_media_info.send_codecs.end()) { outbound_video->codec_id = GetCodecIdAndMaybeCreateCodecStats( @@ -778,9 +779,9 @@ CreateOutboundRTPStreamStatsFromVideoSenderInfo( } } outbound_video->fir_count = - static_cast(video_sender_info.firs_rcvd); + static_cast(video_sender_info.firs_received); outbound_video->pli_count = - static_cast(video_sender_info.plis_rcvd); + static_cast(video_sender_info.plis_received); if (video_sender_info.qp_sum.has_value()) outbound_video->qp_sum = *video_sender_info.qp_sum; if (video_sender_info.target_bitrate.has_value() && @@ -828,7 +829,7 @@ CreateOutboundRTPStreamStatsFromVideoSenderInfo( } if (video_sender_info.power_efficient_encoder.has_value()) { outbound_video->power_efficient_encoder = - video_sender_info.power_efficient_encoder.value(); + *video_sender_info.power_efficient_encoder; } if (video_sender_info.scalability_mode) { outbound_video->scalability_mode = std::string( @@ -851,7 +852,7 @@ ProduceRemoteInboundRtpStreamStatsFromReportBlockData( auto remote_inbound = std::make_unique( RTCRemoteInboundRtpStreamStatsIdFromSourceSsrc(media_type, report_block.source_ssrc), - Timestamp::Micros(report_block_data.report_block_timestamp_utc_us())); + report_block_data.report_block_timestamp_utc()); remote_inbound->ssrc = report_block.source_ssrc; remote_inbound->kind = media_type == cricket::MEDIA_TYPE_AUDIO ? "audio" : "video"; @@ -860,12 +861,10 @@ ProduceRemoteInboundRtpStreamStatsFromReportBlockData( static_cast(report_block.fraction_lost) / (1 << 8); if (report_block_data.num_rtts() > 0) { remote_inbound->round_trip_time = - static_cast(report_block_data.last_rtt_ms()) / - rtc::kNumMillisecsPerSec; + report_block_data.last_rtt().seconds(); } remote_inbound->total_round_trip_time = - static_cast(report_block_data.sum_rtt_ms()) / - rtc::kNumMillisecsPerSec; + report_block_data.sum_rtts().seconds(); remote_inbound->round_trip_time_measurements = report_block_data.num_rtts(); @@ -1294,12 +1293,11 @@ RTCStatsCollector::CreateReportFilteredBySelector( for (const auto* outbound_rtp : report->GetStatsOfType()) { RTC_DCHECK(outbound_rtp->ssrc.is_defined()); - auto it = std::find_if( - encodings.begin(), encodings.end(), - [ssrc = - *outbound_rtp->ssrc](const RtpEncodingParameters& encoding) { - return encoding.ssrc.has_value() && encoding.ssrc.value() == ssrc; - }); + auto it = std::find_if(encodings.begin(), encodings.end(), + [ssrc = *outbound_rtp->ssrc]( + const RtpEncodingParameters& encoding) { + return encoding.ssrc == ssrc; + }); if (it != encodings.end()) { rtpstream_ids.push_back(outbound_rtp->id()); } @@ -1499,7 +1497,6 @@ void RTCStatsCollector::ProducePartialResultsOnSignalingThreadImpl( RTC_DCHECK_RUN_ON(signaling_thread_); rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; - ProduceDataChannelStats_s(timestamp, partial_report); ProduceMediaStreamStats_s(timestamp, partial_report); ProduceMediaStreamTrackStats_s(timestamp, partial_report); ProduceMediaSourceStats_s(timestamp, partial_report); @@ -1519,6 +1516,8 @@ void RTCStatsCollector::ProducePartialResultsOnNetworkThread( // `network_report_event_` is reset before this method is invoked. network_report_ = RTCStatsReport::Create(timestamp); + ProduceDataChannelStats_n(timestamp, network_report_.get()); + std::set transport_names; if (sctp_transport_name) { transport_names.emplace(std::move(*sctp_transport_name)); @@ -1653,10 +1652,10 @@ void RTCStatsCollector::ProduceCertificateStats_n( } } -void RTCStatsCollector::ProduceDataChannelStats_s( +void RTCStatsCollector::ProduceDataChannelStats_n( Timestamp timestamp, RTCStatsReport* report) const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; std::vector data_stats = pc_->GetDataChannelStats(); for (const auto& stats : data_stats) { @@ -2006,8 +2005,8 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( continue; // Inbound. auto inbound_audio = CreateInboundAudioStreamStats( - stats.track_media_info_map.voice_media_info().value(), - voice_receiver_info, transport_id, mid, timestamp, report); + *stats.track_media_info_map.voice_media_info(), voice_receiver_info, + transport_id, mid, timestamp, report); // TODO(hta): This lookup should look for the sender, not the track. rtc::scoped_refptr audio_track = stats.track_media_info_map.GetAudioTrack(voice_receiver_info); @@ -2055,8 +2054,7 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n( if (!voice_sender_info.connected()) continue; auto outbound_audio = CreateOutboundRTPStreamStatsFromVoiceSenderInfo( - transport_id, mid, - stats.track_media_info_map.voice_media_info().value(), + transport_id, mid, *stats.track_media_info_map.voice_media_info(), voice_sender_info, timestamp, report); rtc::scoped_refptr audio_track = stats.track_media_info_map.GetAudioTrack(voice_sender_info); @@ -2115,8 +2113,7 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( if (!video_receiver_info.connected()) continue; auto inbound_video = CreateInboundRTPStreamStatsFromVideoReceiverInfo( - transport_id, mid, - stats.track_media_info_map.video_media_info().value(), + transport_id, mid, *stats.track_media_info_map.video_media_info(), video_receiver_info, timestamp, report); rtc::scoped_refptr video_track = stats.track_media_info_map.GetVideoTrack(video_receiver_info); @@ -2140,8 +2137,7 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n( if (!video_sender_info.connected()) continue; auto outbound_video = CreateOutboundRTPStreamStatsFromVideoSenderInfo( - transport_id, mid, - stats.track_media_info_map.video_media_info().value(), + transport_id, mid, *stats.track_media_info_map.video_media_info(), video_sender_info, timestamp, report); rtc::scoped_refptr video_track = stats.track_media_info_map.GetVideoTrack(video_sender_info); @@ -2493,17 +2489,18 @@ void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w_n() { } void RTCStatsCollector::OnSctpDataChannelStateChanged( - DataChannelInterface* channel, + int channel_id, DataChannelInterface::DataState state) { RTC_DCHECK_RUN_ON(signaling_thread_); if (state == DataChannelInterface::DataState::kOpen) { - bool result = internal_record_.opened_data_channels.insert(channel).second; + bool result = + internal_record_.opened_data_channels.insert(channel_id).second; RTC_DCHECK(result); ++internal_record_.data_channels_opened; } else if (state == DataChannelInterface::DataState::kClosed) { // Only channels that have been fully opened (and have increased the // `data_channels_opened_` counter) increase the closed counter. - if (internal_record_.opened_data_channels.erase(channel)) { + if (internal_record_.opened_data_channels.erase(channel_id)) { ++internal_record_.data_channels_closed; } } diff --git a/third_party/libwebrtc/pc/rtc_stats_collector.h b/third_party/libwebrtc/pc/rtc_stats_collector.h index 7c7c177ebeaa2..34962bf5f7ae7 100644 --- a/third_party/libwebrtc/pc/rtc_stats_collector.h +++ b/third_party/libwebrtc/pc/rtc_stats_collector.h @@ -91,7 +91,7 @@ class RTCStatsCollector : public rtc::RefCountInterface { void WaitForPendingRequest(); // Called by the PeerConnection instance when data channel states change. - void OnSctpDataChannelStateChanged(DataChannelInterface* channel, + void OnSctpDataChannelStateChanged(int channel_id, DataChannelInterface::DataState state); protected: @@ -186,7 +186,7 @@ class RTCStatsCollector : public rtc::RefCountInterface { const std::map& transport_cert_stats, RTCStatsReport* report) const; // Produces `RTCDataChannelStats`. - void ProduceDataChannelStats_s(Timestamp timestamp, + void ProduceDataChannelStats_n(Timestamp timestamp, RTCStatsReport* report) const; // Produces `RTCIceCandidatePairStats` and `RTCIceCandidateStats`. void ProduceIceCandidateAndPairStats_n( @@ -321,12 +321,9 @@ class RTCStatsCollector : public rtc::RefCountInterface { // before reaching the open state does not affect these counters. uint32_t data_channels_opened; uint32_t data_channels_closed; - // Identifies by address channels that have been opened, which remain in the - // set until they have been fully closed. - // NOTE: There is no reference held here or any other type of guarantee that - // these pointers remain valid. So they MUST NOT be followed; hence, void* - // is used and not the explicit type. - webrtc::flat_set opened_data_channels; + // Identifies channels that have been opened, whose internal id is stored in + // the set until they have been fully closed. + webrtc::flat_set opened_data_channels; }; InternalRecord internal_record_; }; diff --git a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc index 3b63f2fb1596f..9b0466d1b74d7 100644 --- a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc +++ b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc @@ -670,7 +670,8 @@ class RTCStatsCollectorTest : public ::testing::Test { RTCStatsCollectorTest() : pc_(rtc::make_ref_counted()), stats_(new RTCStatsCollectorWrapper(pc_)), - data_channel_controller_(new FakeDataChannelController()) {} + data_channel_controller_( + new FakeDataChannelController(pc_->network_thread())) {} void ExpectReportContainsCertificateInfo( const rtc::scoped_refptr& report, @@ -2122,8 +2123,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { EXPECT_EQ(expected, report->Get("P")->cast_to()); } - // TODO(bugs.webrtc.org/11547): Supply a separate network thread. - FakeDataChannelController controller; + FakeDataChannelController controller(pc_->network_thread()); rtc::scoped_refptr dummy_channel_a = SctpDataChannel::Create( controller.weak_ptr(), "DummyChannelA", false, InternalDataChannelInit(), rtc::Thread::Current(), rtc::Thread::Current()); @@ -2132,10 +2132,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { rtc::Thread::Current(), rtc::Thread::Current()); stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_a.get(), DataChannelInterface::DataState::kOpen); + dummy_channel_a->internal_id(), DataChannelInterface::DataState::kOpen); // Closing a channel that is not opened should not affect the counts. stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_b.get(), DataChannelInterface::DataState::kClosed); + dummy_channel_b->internal_id(), DataChannelInterface::DataState::kClosed); { rtc::scoped_refptr report = @@ -2148,9 +2148,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { } stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_b.get(), DataChannelInterface::DataState::kOpen); + dummy_channel_b->internal_id(), DataChannelInterface::DataState::kOpen); stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_b.get(), DataChannelInterface::DataState::kClosed); + dummy_channel_b->internal_id(), DataChannelInterface::DataState::kClosed); { rtc::scoped_refptr report = @@ -2165,7 +2165,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { // Re-opening a data channel (or opening a new data channel that is re-using // the same address in memory) should increase the opened count. stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_b.get(), DataChannelInterface::DataState::kOpen); + dummy_channel_b->internal_id(), DataChannelInterface::DataState::kOpen); { rtc::scoped_refptr report = @@ -2178,9 +2178,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { } stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_a.get(), DataChannelInterface::DataState::kClosed); + dummy_channel_a->internal_id(), DataChannelInterface::DataState::kClosed); stats_->stats_collector()->OnSctpDataChannelStateChanged( - dummy_channel_b.get(), DataChannelInterface::DataState::kClosed); + dummy_channel_b->internal_id(), DataChannelInterface::DataState::kClosed); { rtc::scoped_refptr report = @@ -2473,12 +2473,12 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Audio) { voice_media_info.receivers[0].local_stats[0].ssrc = 1; voice_media_info.receivers[0].packets_lost = -1; // Signed per RFC3550 voice_media_info.receivers[0].packets_discarded = 7788; - voice_media_info.receivers[0].packets_rcvd = 2; + voice_media_info.receivers[0].packets_received = 2; voice_media_info.receivers[0].nacks_sent = 5; voice_media_info.receivers[0].fec_packets_discarded = 5566; voice_media_info.receivers[0].fec_packets_received = 6677; - voice_media_info.receivers[0].payload_bytes_rcvd = 3; - voice_media_info.receivers[0].header_and_padding_bytes_rcvd = 4; + voice_media_info.receivers[0].payload_bytes_received = 3; + voice_media_info.receivers[0].header_and_padding_bytes_received = 4; voice_media_info.receivers[0].codec_payload_type = 42; voice_media_info.receivers[0].jitter_ms = 4500; voice_media_info.receivers[0].jitter_buffer_delay_seconds = 1.0; @@ -2636,10 +2636,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) { video_media_info.receivers[0].local_stats.push_back( cricket::SsrcReceiverInfo()); video_media_info.receivers[0].local_stats[0].ssrc = 1; - video_media_info.receivers[0].packets_rcvd = 2; + video_media_info.receivers[0].packets_received = 2; video_media_info.receivers[0].packets_lost = 42; - video_media_info.receivers[0].payload_bytes_rcvd = 3; - video_media_info.receivers[0].header_and_padding_bytes_rcvd = 12; + video_media_info.receivers[0].payload_bytes_received = 3; + video_media_info.receivers[0].header_and_padding_bytes_received = 12; video_media_info.receivers[0].codec_payload_type = 42; video_media_info.receivers[0].firs_sent = 5; video_media_info.receivers[0].plis_sent = 6; @@ -2679,7 +2679,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) { // Note: these two values intentionally differ, // only the decoded one should show up. - video_media_info.receivers[0].framerate_rcvd = 15; + video_media_info.receivers[0].framerate_received = 15; video_media_info.receivers[0].framerate_decoded = 5; RtpCodecParameters codec_parameters; @@ -2848,7 +2848,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Audio) { voice_media_info.senders[0].payload_bytes_sent = 3; voice_media_info.senders[0].header_and_padding_bytes_sent = 12; voice_media_info.senders[0].retransmitted_bytes_sent = 30; - voice_media_info.senders[0].nacks_rcvd = 31; + voice_media_info.senders[0].nacks_received = 31; voice_media_info.senders[0].target_bitrate = 32000; voice_media_info.senders[0].codec_payload_type = 42; voice_media_info.senders[0].active = true; @@ -2910,9 +2910,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) { video_media_info.senders.push_back(cricket::VideoSenderInfo()); video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo()); video_media_info.senders[0].local_stats[0].ssrc = 1; - video_media_info.senders[0].firs_rcvd = 2; - video_media_info.senders[0].plis_rcvd = 3; - video_media_info.senders[0].nacks_rcvd = 4; + video_media_info.senders[0].firs_received = 2; + video_media_info.senders[0].plis_received = 3; + video_media_info.senders[0].nacks_received = 4; video_media_info.senders[0].packets_sent = 5; video_media_info.senders[0].retransmitted_packets_sent = 50; video_media_info.senders[0].payload_bytes_sent = 6; @@ -3291,7 +3291,7 @@ TEST_F(RTCStatsCollectorTest, CollectNoStreamRTCOutboundRtpStreamStats_Audio) { voice_media_info.senders[0].payload_bytes_sent = 3; voice_media_info.senders[0].header_and_padding_bytes_sent = 4; voice_media_info.senders[0].retransmitted_bytes_sent = 30; - voice_media_info.senders[0].nacks_rcvd = 31; + voice_media_info.senders[0].nacks_received = 31; voice_media_info.senders[0].codec_payload_type = 42; voice_media_info.senders[0].active = true; @@ -3599,31 +3599,29 @@ class RTCStatsCollectorTestWithParamKind // RTCCodecStats (codecId, jitter) and without setting up an RTCP transport. TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsCollectedFromReportBlock) { - const int64_t kReportBlockTimestampUtcUs = 123456789; + const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); const uint8_t kFractionLost = 12; - const int64_t kRoundTripTimeSample1Ms = 1234; - const double kRoundTripTimeSample1Seconds = 1.234; - const int64_t kRoundTripTimeSample2Ms = 13000; - const double kRoundTripTimeSample2Seconds = 13; + const TimeDelta kRoundTripTimeSample1 = TimeDelta::Millis(1'234); + const TimeDelta kRoundTripTimeSample2 = TimeDelta::Seconds(13); // The report block's timestamp cannot be from the future, set the fake clock // to match. - fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs)); + fake_clock_.SetTime(kReportBlockTimestampUtc); auto ssrcs = {12, 13}; std::vector report_block_datas; for (auto ssrc : ssrcs) { - RTCPReportBlock report_block; + rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". - report_block.source_ssrc = ssrc; - report_block.packets_lost = 7; - report_block.fraction_lost = kFractionLost; + report_block.SetMediaSsrc(ssrc); + report_block.SetCumulativeLost(7); + report_block.SetFractionLost(kFractionLost); ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs); - report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample1Ms); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); + report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample1); // Only the last sample should be exposed as the // `RTCRemoteInboundRtpStreamStats::round_trip_time`. - report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample2Ms); + report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample2); report_block_datas.push_back(report_block_data); } AddSenderInfoAndMediaChannel("TransportName", report_block_datas, @@ -3633,8 +3631,7 @@ TEST_P(RTCStatsCollectorTestWithParamKind, for (auto ssrc : ssrcs) { std::string stream_id = "" + std::to_string(ssrc); RTCRemoteInboundRtpStreamStats expected_remote_inbound_rtp( - "RI" + MediaTypeCharStr() + stream_id, - Timestamp::Micros(kReportBlockTimestampUtcUs)); + "RI" + MediaTypeCharStr() + stream_id, kReportBlockTimestampUtc); expected_remote_inbound_rtp.ssrc = ssrc; expected_remote_inbound_rtp.fraction_lost = static_cast(kFractionLost) / (1 << 8); @@ -3645,9 +3642,10 @@ TEST_P(RTCStatsCollectorTestWithParamKind, expected_remote_inbound_rtp.packets_lost = 7; expected_remote_inbound_rtp.local_id = "OTTransportName1" + MediaTypeCharStr() + stream_id; - expected_remote_inbound_rtp.round_trip_time = kRoundTripTimeSample2Seconds; + expected_remote_inbound_rtp.round_trip_time = + kRoundTripTimeSample2.seconds(); expected_remote_inbound_rtp.total_round_trip_time = - kRoundTripTimeSample1Seconds + kRoundTripTimeSample2Seconds; + (kRoundTripTimeSample1 + kRoundTripTimeSample2).seconds(); expected_remote_inbound_rtp.round_trip_time_measurements = 2; // This test does not set up RTCCodecStats, so `codec_id` and `jitter` are // expected to be missing. These are tested separately. @@ -3668,14 +3666,14 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsRttMissingBeforeMeasurement) { - constexpr int64_t kReportBlockTimestampUtcUs = 123456789; + constexpr Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); - RTCPReportBlock report_block; + rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". - report_block.source_ssrc = 12; + report_block.SetMediaSsrc(12); ReportBlockData report_block_data; // AddRoundTripTimeSample() not called. - report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); AddSenderInfoAndMediaChannel("TransportName", {report_block_data}, absl::nullopt); @@ -3694,15 +3692,15 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithTimestampFromReportBlock) { - const int64_t kReportBlockTimestampUtcUs = 123456789; - fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs)); + const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + fake_clock_.SetTime(kReportBlockTimestampUtc); - RTCPReportBlock report_block; + rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". - report_block.source_ssrc = 12; + report_block.SetMediaSsrc(12); ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); AddSenderInfoAndMediaChannel("TransportName", {report_block_data}, absl::nullopt); @@ -3719,24 +3717,23 @@ TEST_P(RTCStatsCollectorTestWithParamKind, // Even though the report time is different, the remote-inbound-rtp timestamp // is of the time that the report block was received. - EXPECT_EQ(Timestamp::Micros(kReportBlockTimestampUtcUs + 1234), - report->timestamp()); - EXPECT_EQ(Timestamp::Micros(kReportBlockTimestampUtcUs), - remote_inbound_rtp.timestamp()); + EXPECT_EQ(report->timestamp(), + kReportBlockTimestampUtc + TimeDelta::Micros(1234)); + EXPECT_EQ(remote_inbound_rtp.timestamp(), kReportBlockTimestampUtc); } TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithCodecBasedMembers) { - const int64_t kReportBlockTimestampUtcUs = 123456789; - fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs)); + const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + fake_clock_.SetTime(kReportBlockTimestampUtc); - RTCPReportBlock report_block; + rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". - report_block.source_ssrc = 12; - report_block.jitter = 5000; + report_block.SetMediaSsrc(12); + report_block.SetJitter(5000); ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); RtpCodecParameters codec; codec.payload_type = 3; @@ -3763,15 +3760,15 @@ TEST_P(RTCStatsCollectorTestWithParamKind, TEST_P(RTCStatsCollectorTestWithParamKind, RTCRemoteInboundRtpStreamStatsWithRtcpTransport) { - const int64_t kReportBlockTimestampUtcUs = 123456789; - fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs)); + const Timestamp kReportBlockTimestampUtc = Timestamp::Micros(123456789); + fake_clock_.SetTime(kReportBlockTimestampUtc); - RTCPReportBlock report_block; + rtcp::ReportBlock report_block; // The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the // `source_ssrc`, "SSRC of the RTP packet sender". - report_block.source_ssrc = 12; + report_block.SetMediaSsrc(12); ReportBlockData report_block_data; - report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs); + report_block_data.SetReportBlock(0, report_block, kReportBlockTimestampUtc); cricket::TransportChannelStats rtp_transport_channel_stats; rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP; diff --git a/third_party/libwebrtc/pc/rtp_transport.cc b/third_party/libwebrtc/pc/rtp_transport.cc index 1aa86604677a2..8ef597f58ff25 100644 --- a/third_party/libwebrtc/pc/rtp_transport.cc +++ b/third_party/libwebrtc/pc/rtp_transport.cc @@ -193,8 +193,9 @@ void RtpTransport::DemuxPacket(rtc::CopyOnWriteBuffer packet, } if (!rtp_demuxer_.OnRtpPacket(parsed_packet)) { - RTC_LOG(LS_WARNING) << "Failed to demux RTP packet: " + RTC_LOG(LS_VERBOSE) << "Failed to demux RTP packet: " << RtpDemuxer::DescribePacket(parsed_packet); + SignalUnDemuxableRtpPacketReceived(parsed_packet); } } diff --git a/third_party/libwebrtc/pc/rtp_transport_internal.h b/third_party/libwebrtc/pc/rtp_transport_internal.h index 9e816113f1652..264be134a426a 100644 --- a/third_party/libwebrtc/pc/rtp_transport_internal.h +++ b/third_party/libwebrtc/pc/rtp_transport_internal.h @@ -53,10 +53,15 @@ class RtpTransportInternal : public sigslot::has_slots<> { sigslot::signal1 SignalReadyToSend; // Called whenever an RTCP packet is received. There is no equivalent signal - // for RTP packets because they would be forwarded to the BaseChannel through - // the RtpDemuxer callback. + // for demuxable RTP packets because they would be forwarded to the + // BaseChannel through the RtpDemuxer callback. sigslot::signal2 SignalRtcpPacketReceived; + // Called whenever a RTP packet that can not be demuxed by the transport is + // received. + sigslot::signal + SignalUnDemuxableRtpPacketReceived; + // Called whenever the network route of the P2P layer transport changes. // The argument is an optional network route. sigslot::signal1> SignalNetworkRouteChanged; diff --git a/third_party/libwebrtc/pc/rtp_transport_unittest.cc b/third_party/libwebrtc/pc/rtp_transport_unittest.cc index 0e6af734f3960..e3d410103777d 100644 --- a/third_party/libwebrtc/pc/rtp_transport_unittest.cc +++ b/third_party/libwebrtc/pc/rtp_transport_unittest.cc @@ -288,6 +288,7 @@ TEST(RtpTransportTest, SignalHandledRtpPayloadType) { rtc::Buffer rtp_data(kRtpData, kRtpLen); fake_rtp.SendPacket(rtp_data.data(), kRtpLen, options, flags); EXPECT_EQ(1, observer.rtp_count()); + EXPECT_EQ(0, observer.un_demuxable_rtp_count()); EXPECT_EQ(0, observer.rtcp_count()); // Remove the sink before destroying the transport. transport.UnregisterRtpDemuxerSink(&observer); @@ -311,6 +312,7 @@ TEST(RtpTransportTest, DontSignalUnhandledRtpPayloadType) { rtc::Buffer rtp_data(kRtpData, kRtpLen); fake_rtp.SendPacket(rtp_data.data(), kRtpLen, options, flags); EXPECT_EQ(0, observer.rtp_count()); + EXPECT_EQ(1, observer.un_demuxable_rtp_count()); EXPECT_EQ(0, observer.rtcp_count()); // Remove the sink before destroying the transport. transport.UnregisterRtpDemuxerSink(&observer); diff --git a/third_party/libwebrtc/pc/sctp_data_channel.cc b/third_party/libwebrtc/pc/sctp_data_channel.cc index 24efae674c5b4..dda9110bfc6b5 100644 --- a/third_party/libwebrtc/pc/sctp_data_channel.cc +++ b/third_party/libwebrtc/pc/sctp_data_channel.cc @@ -15,7 +15,6 @@ #include #include -#include "absl/cleanup/cleanup.h" #include "media/sctp/sctp_transport_internal.h" #include "pc/proxy.h" #include "rtc_base/checks.h" @@ -36,10 +35,10 @@ int GenerateUniqueId() { } // Define proxy for DataChannelInterface. -BEGIN_PRIMARY_PROXY_MAP(DataChannel) +BEGIN_PROXY_MAP(DataChannel) PROXY_PRIMARY_THREAD_DESTRUCTOR() -PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*) -PROXY_METHOD0(void, UnregisterObserver) +BYPASS_PROXY_METHOD1(void, RegisterObserver, DataChannelObserver*) +BYPASS_PROXY_METHOD0(void, UnregisterObserver) BYPASS_PROXY_CONSTMETHOD0(std::string, label) BYPASS_PROXY_CONSTMETHOD0(bool, reliable) BYPASS_PROXY_CONSTMETHOD0(bool, ordered) @@ -50,20 +49,22 @@ BYPASS_PROXY_CONSTMETHOD0(absl::optional, maxPacketLifeTime) BYPASS_PROXY_CONSTMETHOD0(std::string, protocol) BYPASS_PROXY_CONSTMETHOD0(bool, negotiated) // Can't bypass the proxy since the id may change. -PROXY_CONSTMETHOD0(int, id) +PROXY_SECONDARY_CONSTMETHOD0(int, id) BYPASS_PROXY_CONSTMETHOD0(Priority, priority) -PROXY_CONSTMETHOD0(DataState, state) -PROXY_CONSTMETHOD0(RTCError, error) -PROXY_CONSTMETHOD0(uint32_t, messages_sent) -PROXY_CONSTMETHOD0(uint64_t, bytes_sent) -PROXY_CONSTMETHOD0(uint32_t, messages_received) -PROXY_CONSTMETHOD0(uint64_t, bytes_received) -PROXY_CONSTMETHOD0(uint64_t, buffered_amount) -PROXY_METHOD0(void, Close) -// TODO(bugs.webrtc.org/11547): Change to run on the network thread. -PROXY_METHOD1(bool, Send, const DataBuffer&) +BYPASS_PROXY_CONSTMETHOD0(DataState, state) +BYPASS_PROXY_CONSTMETHOD0(RTCError, error) +PROXY_SECONDARY_CONSTMETHOD0(uint32_t, messages_sent) +PROXY_SECONDARY_CONSTMETHOD0(uint64_t, bytes_sent) +PROXY_SECONDARY_CONSTMETHOD0(uint32_t, messages_received) +PROXY_SECONDARY_CONSTMETHOD0(uint64_t, bytes_received) +PROXY_SECONDARY_CONSTMETHOD0(uint64_t, buffered_amount) +PROXY_SECONDARY_METHOD0(void, Close) +PROXY_SECONDARY_METHOD1(bool, Send, const DataBuffer&) +BYPASS_PROXY_METHOD2(void, + SendAsync, + DataBuffer, + absl::AnyInvocable) END_PROXY_MAP(DataChannel) - } // namespace InternalDataChannelInit::InternalDataChannelInit(const DataChannelInit& base) @@ -117,10 +118,6 @@ bool InternalDataChannelInit::IsValid() const { return true; } -SctpSidAllocator::SctpSidAllocator() { - sequence_checker_.Detach(); -} - StreamId SctpSidAllocator::AllocateSid(rtc::SSLRole role) { RTC_DCHECK_RUN_ON(&sequence_checker_); int potential_sid = (role == rtc::SSL_CLIENT) ? 0 : 1; @@ -146,6 +143,143 @@ void SctpSidAllocator::ReleaseSid(StreamId sid) { used_sids_.erase(sid); } +// A DataChannelObserver implementation that offers backwards compatibility with +// implementations that aren't yet ready to be called back on the network +// thread. This implementation posts events to the signaling thread where +// events are delivered. +// In the class, and together with the `SctpDataChannel` implementation, there's +// special handling for the `state()` property whereby if that property is +// queried on the channel object while inside an event callback, we return +// the state that was active at the time the event was issued. This is to avoid +// a problem with calling the `state()` getter on the proxy, which would do +// a blocking call to the network thread, effectively flushing operations on +// the network thread that could cause the state to change and eventually return +// a misleading or arguably, wrong, state value to the callback implementation. +// As a future improvement to the ObserverAdapter, we could do the same for +// other properties that need to be read on the network thread. Eventually +// all implementations should expect to be called on the network thread though +// and the ObserverAdapter no longer be necessary. +class SctpDataChannel::ObserverAdapter : public DataChannelObserver { + public: + explicit ObserverAdapter( + SctpDataChannel* channel, + rtc::scoped_refptr signaling_safety) + : channel_(channel), signaling_safety_(std::move(signaling_safety)) {} + + bool IsInsideCallback() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return cached_getters_ != nullptr; + } + + DataChannelInterface::DataState cached_state() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsInsideCallback()); + return cached_getters_->state(); + } + + RTCError cached_error() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(IsInsideCallback()); + return cached_getters_->error(); + } + + void SetDelegate(DataChannelObserver* delegate) { + RTC_DCHECK_RUN_ON(signaling_thread()); + delegate_ = delegate; + safety_.reset(PendingTaskSafetyFlag::CreateDetached()); + } + + static void DeleteOnSignalingThread( + std::unique_ptr observer) { + auto* signaling_thread = observer->signaling_thread(); + if (!signaling_thread->IsCurrent()) + signaling_thread->PostTask([observer = std::move(observer)]() {}); + } + + private: + class CachedGetters { + public: + explicit CachedGetters(ObserverAdapter* adapter) + : adapter_(adapter), + cached_state_(adapter_->channel_->state()), + cached_error_(adapter_->channel_->error()) { + RTC_DCHECK_RUN_ON(adapter->network_thread()); + } + + ~CachedGetters() { + if (!was_dropped_) { + RTC_DCHECK_RUN_ON(adapter_->signaling_thread()); + RTC_DCHECK_EQ(adapter_->cached_getters_, this); + adapter_->cached_getters_ = nullptr; + } + } + + bool PrepareForCallback() { + RTC_DCHECK_RUN_ON(adapter_->signaling_thread()); + RTC_DCHECK(was_dropped_); + was_dropped_ = false; + adapter_->cached_getters_ = this; + return adapter_->delegate_ && adapter_->signaling_safety_->alive(); + } + + RTCError error() { return cached_error_; } + DataChannelInterface::DataState state() { return cached_state_; } + + private: + ObserverAdapter* const adapter_; + bool was_dropped_ = true; + const DataChannelInterface::DataState cached_state_; + const RTCError cached_error_; + }; + + void OnStateChange() override { + RTC_DCHECK_RUN_ON(network_thread()); + signaling_thread()->PostTask( + SafeTask(safety_.flag(), + [this, cached_state = std::make_unique(this)] { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (cached_state->PrepareForCallback()) + delegate_->OnStateChange(); + })); + } + + void OnMessage(const DataBuffer& buffer) override { + RTC_DCHECK_RUN_ON(network_thread()); + signaling_thread()->PostTask(SafeTask( + safety_.flag(), [this, buffer = buffer, + cached_state = std::make_unique(this)] { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (cached_state->PrepareForCallback()) + delegate_->OnMessage(buffer); + })); + } + + void OnBufferedAmountChange(uint64_t sent_data_size) override { + RTC_DCHECK_RUN_ON(network_thread()); + signaling_thread()->PostTask(SafeTask( + safety_.flag(), [this, sent_data_size, + cached_state = std::make_unique(this)] { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (cached_state->PrepareForCallback()) + delegate_->OnBufferedAmountChange(sent_data_size); + })); + } + + bool IsOkToCallOnTheNetworkThread() override { return true; } + + rtc::Thread* signaling_thread() const { return signaling_thread_; } + rtc::Thread* network_thread() const { return channel_->network_thread_; } + + DataChannelObserver* delegate_ RTC_GUARDED_BY(signaling_thread()) = nullptr; + SctpDataChannel* const channel_; + // Make sure to keep our own signaling_thread_ pointer to avoid dereferencing + // `channel_` in the `RTC_DCHECK_RUN_ON` checks on the signaling thread. + rtc::Thread* const signaling_thread_{channel_->signaling_thread_}; + ScopedTaskSafety safety_; + rtc::scoped_refptr signaling_safety_; + CachedGetters* cached_getters_ RTC_GUARDED_BY(signaling_thread()) = nullptr; +}; + // static rtc::scoped_refptr SctpDataChannel::Create( rtc::WeakPtr controller, @@ -154,7 +288,6 @@ rtc::scoped_refptr SctpDataChannel::Create( const InternalDataChannelInit& config, rtc::Thread* signaling_thread, rtc::Thread* network_thread) { - RTC_DCHECK(controller); RTC_DCHECK(config.IsValid()); return rtc::make_ref_counted( config, std::move(controller), label, connected_to_transport, @@ -163,10 +296,15 @@ rtc::scoped_refptr SctpDataChannel::Create( // static rtc::scoped_refptr SctpDataChannel::CreateProxy( - rtc::scoped_refptr channel) { - // TODO(bugs.webrtc.org/11547): incorporate the network thread in the proxy. + rtc::scoped_refptr channel, + rtc::scoped_refptr signaling_safety) { + // Copy thread params to local variables before `std::move()`. auto* signaling_thread = channel->signaling_thread_; - return DataChannelProxy::Create(signaling_thread, std::move(channel)); + auto* network_thread = channel->network_thread_; + channel->observer_adapter_ = std::make_unique( + channel.get(), std::move(signaling_safety)); + return DataChannelProxy::Create(signaling_thread, network_thread, + std::move(channel)); } SctpDataChannel::SctpDataChannel( @@ -178,7 +316,7 @@ SctpDataChannel::SctpDataChannel( rtc::Thread* network_thread) : signaling_thread_(signaling_thread), network_thread_(network_thread), - id_(config.id), + id_n_(config.id), internal_id_(GenerateUniqueId()), label_(label), protocol_(config.protocol), @@ -188,12 +326,15 @@ SctpDataChannel::SctpDataChannel( negotiated_(config.negotiated), ordered_(config.ordered), observer_(nullptr), - controller_(std::move(controller)), - connected_to_transport_(connected_to_transport) { - RTC_DCHECK_RUN_ON(signaling_thread_); + controller_(std::move(controller)) { + RTC_DCHECK_RUN_ON(network_thread_); + // Since we constructed on the network thread we can't (yet) check the + // `controller_` pointer since doing so will trigger a thread check. RTC_UNUSED(network_thread_); RTC_DCHECK(config.IsValid()); - RTC_DCHECK(controller_); + + if (connected_to_transport) + network_safety_->SetAlive(); switch (config.open_handshake_role) { case InternalDataChannelInit::kNone: // pre-negotiated @@ -206,27 +347,90 @@ SctpDataChannel::SctpDataChannel( handshake_state_ = kHandshakeShouldSendAck; break; } - - // Try to connect to the transport in case the transport channel already - // exists. - if (id_.HasValue()) { - controller_->AddSctpDataStream(id_); - } } SctpDataChannel::~SctpDataChannel() { - RTC_DCHECK_RUN_ON(signaling_thread_); + if (observer_adapter_) + ObserverAdapter::DeleteOnSignalingThread(std::move(observer_adapter_)); } void SctpDataChannel::RegisterObserver(DataChannelObserver* observer) { - RTC_DCHECK_RUN_ON(signaling_thread_); - observer_ = observer; - DeliverQueuedReceivedData(); + // Note: at this point, we do not know on which thread we're being called + // from since this method bypasses the proxy. On Android in particular, + // registration methods are called from unknown threads. + + // Check if we should set up an observer adapter that will make sure that + // callbacks are delivered on the signaling thread rather than directly + // on the network thread. + const auto* current_thread = rtc::Thread::Current(); + // TODO(webrtc:11547): Eventually all DataChannelObserver implementations + // should be called on the network thread and IsOkToCallOnTheNetworkThread(). + if (!observer->IsOkToCallOnTheNetworkThread()) { + RTC_LOG(LS_WARNING) << "DataChannelObserver - adapter needed"; + auto prepare_observer = [&]() { + RTC_DCHECK(observer_adapter_) << "CreateProxy hasn't been called"; + observer_adapter_->SetDelegate(observer); + return observer_adapter_.get(); + }; + // Instantiate the adapter in the right context and then substitute the + // observer pointer the SctpDataChannel will call back on, with the adapter. + if (signaling_thread_ == current_thread) { + observer = prepare_observer(); + } else { + observer = signaling_thread_->BlockingCall(std::move(prepare_observer)); + } + } + + // Now do the observer registration on the network thread. + auto register_observer = [&] { + RTC_DCHECK_RUN_ON(network_thread_); + observer_ = observer; + DeliverQueuedReceivedData(); + }; + + if (network_thread_ == current_thread) { + register_observer(); + } else { + network_thread_->BlockingCall(std::move(register_observer)); + } } void SctpDataChannel::UnregisterObserver() { - RTC_DCHECK_RUN_ON(signaling_thread_); - observer_ = nullptr; + // Note: As with `RegisterObserver`, the proxy is being bypassed. + const auto* current_thread = rtc::Thread::Current(); + // Callers must not be invoking the unregistration from the network thread + // (assuming a multi-threaded environment where we have a dedicated network + // thread). That would indicate non-network related work happening on the + // network thread or that unregistration is being done from within a callback + // (without unwinding the stack, which is a requirement). + // The network thread is not allowed to make blocking calls to the signaling + // thread, so that would blow up if attempted. Since we support an adapter + // for observers that are not safe to call on the network thread, we do + // need to check+free it on the signaling thread. + RTC_DCHECK(current_thread != network_thread_ || + network_thread_ == signaling_thread_); + + auto unregister_observer = [&] { + RTC_DCHECK_RUN_ON(network_thread_); + observer_ = nullptr; + }; + + if (current_thread == network_thread_) { + unregister_observer(); + } else { + network_thread_->BlockingCall(std::move(unregister_observer)); + } + + auto clear_observer = [&]() { + if (observer_adapter_) + observer_adapter_->SetDelegate(nullptr); + }; + + if (current_thread != signaling_thread_) { + signaling_thread_->BlockingCall(std::move(clear_observer)); + } else { + clear_observer(); + } } std::string SctpDataChannel::label() const { @@ -268,7 +472,8 @@ bool SctpDataChannel::negotiated() const { } int SctpDataChannel::id() const { - return id_.stream_id_int(); + RTC_DCHECK_RUN_ON(network_thread_); + return id_n_.stream_id_int(); } Priority SctpDataChannel::priority() const { @@ -276,12 +481,12 @@ Priority SctpDataChannel::priority() const { } uint64_t SctpDataChannel::buffered_amount() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); return queued_send_data_.byte_count(); } void SctpDataChannel::Close() { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); if (state_ == kClosing || state_ == kClosed) return; SetState(kClosing); @@ -290,70 +495,130 @@ void SctpDataChannel::Close() { } SctpDataChannel::DataState SctpDataChannel::state() const { - RTC_DCHECK_RUN_ON(signaling_thread_); - return state_; + // Note: The proxy is bypassed for the `state()` accessor. This is to allow + // observer callbacks to query what the new state is from within a state + // update notification without having to do a blocking call to the network + // thread from within a callback. This also makes it so that the returned + // state is guaranteed to be the new state that provoked the state change + // notification, whereby a blocking call to the network thread might end up + // getting put behind other messages on the network thread and eventually + // fetch a different state value (since pending messages might cause the + // state to change in the meantime). + const auto* current_thread = rtc::Thread::Current(); + if (current_thread == signaling_thread_ && observer_adapter_ && + observer_adapter_->IsInsideCallback()) { + return observer_adapter_->cached_state(); + } + + auto return_state = [&] { + RTC_DCHECK_RUN_ON(network_thread_); + return state_; + }; + + return current_thread == network_thread_ + ? return_state() + : network_thread_->BlockingCall(std::move(return_state)); } RTCError SctpDataChannel::error() const { - RTC_DCHECK_RUN_ON(signaling_thread_); - return error_; + const auto* current_thread = rtc::Thread::Current(); + if (current_thread == signaling_thread_ && observer_adapter_ && + observer_adapter_->IsInsideCallback()) { + return observer_adapter_->cached_error(); + } + + auto return_error = [&] { + RTC_DCHECK_RUN_ON(network_thread_); + return error_; + }; + + return current_thread == network_thread_ + ? return_error() + : network_thread_->BlockingCall(std::move(return_error)); } uint32_t SctpDataChannel::messages_sent() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); return messages_sent_; } uint64_t SctpDataChannel::bytes_sent() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); return bytes_sent_; } uint32_t SctpDataChannel::messages_received() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); return messages_received_; } uint64_t SctpDataChannel::bytes_received() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); return bytes_received_; } bool SctpDataChannel::Send(const DataBuffer& buffer) { - RTC_DCHECK_RUN_ON(signaling_thread_); - // TODO(bugs.webrtc.org/11547): Expect this method to be called on the network - // thread. Bring buffer management etc to the network thread and keep the - // operational state management on the signaling thread. + RTC_DCHECK_RUN_ON(network_thread_); + RTCError err = SendImpl(buffer); + if (err.type() == RTCErrorType::INVALID_STATE || + err.type() == RTCErrorType::RESOURCE_EXHAUSTED) { + return false; + } + + // Always return true for SCTP DataChannel per the spec. + return true; +} +// RTC_RUN_ON(network_thread_); +RTCError SctpDataChannel::SendImpl(DataBuffer buffer) { if (state_ != kOpen) { - return false; + error_ = RTCError(RTCErrorType::INVALID_STATE); + return error_; } // If the queue is non-empty, we're waiting for SignalReadyToSend, // so just add to the end of the queue and keep waiting. if (!queued_send_data_.Empty()) { - return QueueSendDataMessage(buffer); + error_ = QueueSendDataMessage(buffer) + ? RTCError::OK() + : RTCError(RTCErrorType::RESOURCE_EXHAUSTED); + return error_; } - SendDataMessage(buffer, true); - - // Always return true for SCTP DataChannel per the spec. - return true; -} - -void SctpDataChannel::SetSctpSid(const StreamId& sid) { - RTC_DCHECK_RUN_ON(signaling_thread_); - RTC_DCHECK(!id_.HasValue()); + return SendDataMessage(buffer, true); +} + +void SctpDataChannel::SendAsync( + DataBuffer buffer, + absl::AnyInvocable on_complete) { + // Note: at this point, we do not know on which thread we're being called + // since this method bypasses the proxy. On Android the thread might be VM + // owned, on other platforms it might be the signaling thread, or in Chrome + // it can be the JS thread. We also don't know if it's consistently the same + // thread. So we always post to the network thread (even if the current thread + // might be the network thread - in theory a call could even come from within + // the `on_complete` callback). + network_thread_->PostTask(SafeTask( + network_safety_, [this, buffer = std::move(buffer), + on_complete = std::move(on_complete)]() mutable { + RTC_DCHECK_RUN_ON(network_thread_); + RTCError err = SendImpl(std::move(buffer)); + if (on_complete) + std::move(on_complete)(err); + })); +} + +void SctpDataChannel::SetSctpSid_n(StreamId sid) { + RTC_DCHECK_RUN_ON(network_thread_); + RTC_DCHECK(!id_n_.HasValue()); RTC_DCHECK(sid.HasValue()); RTC_DCHECK_NE(handshake_state_, kHandshakeWaitingForAck); RTC_DCHECK_EQ(state_, kConnecting); - - id_ = sid; - controller_->AddSctpDataStream(sid); + id_n_ = sid; } void SctpDataChannel::OnClosingProcedureStartedRemotely() { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); if (state_ != kClosing && state_ != kClosed) { // Don't bother sending queued data since the side that initiated the // closure wouldn't receive it anyway. See crbug.com/559394 for a lengthy @@ -369,7 +634,7 @@ void SctpDataChannel::OnClosingProcedureStartedRemotely() { } void SctpDataChannel::OnClosingProcedureComplete() { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); // If the closing procedure is complete, we should have finished sending // all pending data and transitioned to kClosing already. RTC_DCHECK_EQ(state_, kClosing); @@ -378,19 +643,12 @@ void SctpDataChannel::OnClosingProcedureComplete() { } void SctpDataChannel::OnTransportChannelCreated() { - RTC_DCHECK_RUN_ON(signaling_thread_); - RTC_DCHECK(controller_); - - connected_to_transport_ = true; - - // The sid may have been unassigned when controller_->ConnectDataChannel was - // done. So always add the streams even if connected_to_transport_ is true. - if (id_.HasValue()) { - controller_->AddSctpDataStream(id_); - } + RTC_DCHECK_RUN_ON(network_thread_); + network_safety_->SetAlive(); } void SctpDataChannel::OnTransportChannelClosed(RTCError error) { + RTC_DCHECK_RUN_ON(network_thread_); // The SctpTransport is unusable, which could come from multiple reasons: // - the SCTP m= section was rejected // - the DTLS transport is closed @@ -399,7 +657,7 @@ void SctpDataChannel::OnTransportChannelClosed(RTCError error) { } DataChannelStats SctpDataChannel::GetStats() const { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); DataChannelStats stats{internal_id_, id(), label(), protocol(), state(), messages_sent(), messages_received(), bytes_sent(), bytes_received()}; @@ -408,25 +666,25 @@ DataChannelStats SctpDataChannel::GetStats() const { void SctpDataChannel::OnDataReceived(DataMessageType type, const rtc::CopyOnWriteBuffer& payload) { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); if (type == DataMessageType::kControl) { if (handshake_state_ != kHandshakeWaitingForAck) { // Ignore it if we are not expecting an ACK message. RTC_LOG(LS_WARNING) << "DataChannel received unexpected CONTROL message, sid = " - << id_.stream_id_int(); + << id_n_.stream_id_int(); return; } if (ParseDataChannelOpenAckMessage(payload)) { // We can send unordered as soon as we receive the ACK message. handshake_state_ = kHandshakeReady; RTC_LOG(LS_INFO) << "DataChannel received OPEN_ACK message, sid = " - << id_.stream_id_int(); + << id_n_.stream_id_int(); } else { RTC_LOG(LS_WARNING) << "DataChannel failed to parse OPEN_ACK message, sid = " - << id_.stream_id_int(); + << id_n_.stream_id_int(); } return; } @@ -435,7 +693,7 @@ void SctpDataChannel::OnDataReceived(DataMessageType type, type == DataMessageType::kText); RTC_DLOG(LS_VERBOSE) << "DataChannel received DATA message, sid = " - << id_.stream_id_int(); + << id_n_.stream_id_int(); // We can send unordered as soon as we receive any DATA message since the // remote side must have received the OPEN (and old clients do not send // OPEN_ACK). @@ -466,22 +724,9 @@ void SctpDataChannel::OnDataReceived(DataMessageType type, } void SctpDataChannel::OnTransportReady() { - RTC_DCHECK_RUN_ON(signaling_thread_); - - // TODO(tommi, hta): We don't need the `writable_` flag for SCTP datachannels. - // Remove it and just rely on `connected_to_transport_` instead. - // In practice the transport is configured inside - // `PeerConnection::SetupDataChannelTransport_n`, which results in - // `SctpDataChannel` getting the OnTransportChannelCreated callback, and then - // that's immediately followed by calling `transport->SetDataSink` which is - // what triggers the callback to `OnTransportReady()`. - // These steps are currently accomplished via two separate PostTask calls to - // the signaling thread, but could simply be done in single method call on - // the network thread (which incidentally is the thread that we'll need to - // be on for the below `Send*` calls, which currently do a BlockingCall - // from the signaling thread to the network thread. - RTC_DCHECK(connected_to_transport_); - writable_ = true; + RTC_DCHECK_RUN_ON(network_thread_); + RTC_DCHECK(connected_to_transport()); + RTC_DCHECK(id_n_.HasValue()); SendQueuedControlMessages(); SendQueuedDataMessages(); @@ -490,13 +735,13 @@ void SctpDataChannel::OnTransportReady() { } void SctpDataChannel::CloseAbruptlyWithError(RTCError error) { - RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK_RUN_ON(network_thread_); if (state_ == kClosed) { return; } - connected_to_transport_ = false; + network_safety_->SetNotAlive(); // Closing abruptly means any queued data gets thrown away. queued_send_data_.Clear(); @@ -511,13 +756,14 @@ void SctpDataChannel::CloseAbruptlyWithError(RTCError error) { void SctpDataChannel::CloseAbruptlyWithDataChannelFailure( const std::string& message) { + RTC_DCHECK_RUN_ON(network_thread_); RTCError error(RTCErrorType::OPERATION_ERROR_WITH_DATA, message); error.set_error_detail(RTCErrorDetailType::DATA_CHANNEL_FAILURE); CloseAbruptlyWithError(std::move(error)); } +// RTC_RUN_ON(network_thread_). void SctpDataChannel::UpdateState() { - RTC_DCHECK_RUN_ON(signaling_thread_); // UpdateState determines what to do from a few state variables. Include // all conditions required for each state transition here for // clarity. OnTransportReady(true) will send any queued data and then invoke @@ -525,7 +771,7 @@ void SctpDataChannel::UpdateState() { switch (state_) { case kConnecting: { - if (connected_to_transport_) { + if (connected_to_transport() && controller_) { if (handshake_state_ == kHandshakeShouldSendOpen) { rtc::CopyOnWriteBuffer payload; WriteDataChannelOpenMessage(label_, protocol_, priority_, ordered_, @@ -537,15 +783,15 @@ void SctpDataChannel::UpdateState() { WriteDataChannelOpenAckMessage(&payload); SendControlMessage(payload); } - if (writable_ && (handshake_state_ == kHandshakeReady || - handshake_state_ == kHandshakeWaitingForAck)) { + if (handshake_state_ == kHandshakeReady || + handshake_state_ == kHandshakeWaitingForAck) { SetState(kOpen); // If we have received buffers before the channel got writable. // Deliver them now. DeliverQueuedReceivedData(); } } else { - RTC_DCHECK(!id_.HasValue()); + RTC_DCHECK(!id_n_.HasValue()); } break; } @@ -553,7 +799,7 @@ void SctpDataChannel::UpdateState() { break; } case kClosing: { - if (connected_to_transport_) { + if (connected_to_transport() && controller_) { // Wait for all queued data to be sent before beginning the closing // procedure. if (queued_send_data_.Empty() && queued_control_data_.Empty()) { @@ -561,9 +807,9 @@ void SctpDataChannel::UpdateState() { // to complete; after calling RemoveSctpDataStream, // OnClosingProcedureComplete will end up called asynchronously // afterwards. - if (!started_closing_procedure_ && controller_ && id_.HasValue()) { + if (!started_closing_procedure_ && id_n_.HasValue()) { started_closing_procedure_ = true; - controller_->RemoveSctpDataStream(id_); + controller_->RemoveSctpDataStream(id_n_); } } } else { @@ -580,8 +826,8 @@ void SctpDataChannel::UpdateState() { } } +// RTC_RUN_ON(network_thread_). void SctpDataChannel::SetState(DataState state) { - RTC_DCHECK_RUN_ON(signaling_thread_); if (state_ == state) { return; } @@ -595,9 +841,9 @@ void SctpDataChannel::SetState(DataState state) { controller_->OnChannelStateChanged(this, state_); } +// RTC_RUN_ON(network_thread_). void SctpDataChannel::DeliverQueuedReceivedData() { - RTC_DCHECK_RUN_ON(signaling_thread_); - if (!observer_) { + if (!observer_ || state_ != kOpen) { return; } @@ -609,8 +855,8 @@ void SctpDataChannel::DeliverQueuedReceivedData() { } } +// RTC_RUN_ON(network_thread_). void SctpDataChannel::SendQueuedDataMessages() { - RTC_DCHECK_RUN_ON(signaling_thread_); if (queued_send_data_.Empty()) { return; } @@ -619,7 +865,7 @@ void SctpDataChannel::SendQueuedDataMessages() { while (!queued_send_data_.Empty()) { std::unique_ptr buffer = queued_send_data_.PopFront(); - if (!SendDataMessage(*buffer, false)) { + if (!SendDataMessage(*buffer, false).ok()) { // Return the message to the front of the queue if sending is aborted. queued_send_data_.PushFront(std::move(buffer)); break; @@ -627,12 +873,13 @@ void SctpDataChannel::SendQueuedDataMessages() { } } -bool SctpDataChannel::SendDataMessage(const DataBuffer& buffer, - bool queue_if_blocked) { - RTC_DCHECK_RUN_ON(signaling_thread_); +// RTC_RUN_ON(network_thread_). +RTCError SctpDataChannel::SendDataMessage(const DataBuffer& buffer, + bool queue_if_blocked) { SendDataParams send_params; if (!controller_) { - return false; + error_ = RTCError(RTCErrorType::INVALID_STATE); + return error_; } send_params.ordered = ordered_; @@ -649,48 +896,52 @@ bool SctpDataChannel::SendDataMessage(const DataBuffer& buffer, send_params.type = buffer.binary ? DataMessageType::kBinary : DataMessageType::kText; - RTCError error = controller_->SendData(id_, send_params, buffer.data); - - if (error.ok()) { + error_ = controller_->SendData(id_n_, send_params, buffer.data); + if (error_.ok()) { ++messages_sent_; bytes_sent_ += buffer.size(); if (observer_ && buffer.size() > 0) { observer_->OnBufferedAmountChange(buffer.size()); } - return true; + return error_; } - if (error.type() == RTCErrorType::RESOURCE_EXHAUSTED) { - if (!queue_if_blocked || QueueSendDataMessage(buffer)) { - return false; + if (error_.type() == RTCErrorType::RESOURCE_EXHAUSTED) { + if (!queue_if_blocked) + return error_; + + if (QueueSendDataMessage(buffer)) { + error_ = RTCError::OK(); + return error_; } } // Close the channel if the error is not SDR_BLOCK, or if queuing the // message failed. RTC_LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send data, " "send_result = " - << ToString(error.type()) << ":" << error.message(); + << ToString(error_.type()) << ":" << error_.message(); CloseAbruptlyWithError( RTCError(RTCErrorType::NETWORK_ERROR, "Failure to send data")); - return false; + return error_; } +// RTC_RUN_ON(network_thread_). bool SctpDataChannel::QueueSendDataMessage(const DataBuffer& buffer) { - RTC_DCHECK_RUN_ON(signaling_thread_); size_t start_buffered_amount = queued_send_data_.byte_count(); if (start_buffered_amount + buffer.size() > DataChannelInterface::MaxSendQueueSize()) { RTC_LOG(LS_ERROR) << "Can't buffer any more data for the data channel."; + error_ = RTCError(RTCErrorType::RESOURCE_EXHAUSTED); return false; } queued_send_data_.PushBack(std::make_unique(buffer)); return true; } +// RTC_RUN_ON(network_thread_). void SctpDataChannel::SendQueuedControlMessages() { - RTC_DCHECK_RUN_ON(signaling_thread_); PacketQueue control_packets; control_packets.Swap(&queued_control_data_); @@ -700,21 +951,12 @@ void SctpDataChannel::SendQueuedControlMessages() { } } -void SctpDataChannel::QueueControlMessage( - const rtc::CopyOnWriteBuffer& buffer) { - RTC_DCHECK_RUN_ON(signaling_thread_); - queued_control_data_.PushBack(std::make_unique(buffer, true)); -} - +// RTC_RUN_ON(network_thread_). bool SctpDataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { - RTC_DCHECK_RUN_ON(signaling_thread_); - RTC_DCHECK(writable_); - RTC_DCHECK(connected_to_transport_); - RTC_DCHECK(id_.HasValue()); + RTC_DCHECK(connected_to_transport()); + RTC_DCHECK(id_n_.HasValue()); + RTC_DCHECK(controller_); - if (!controller_) { - return false; - } bool is_open_message = handshake_state_ == kHandshakeShouldSendOpen; RTC_DCHECK(!is_open_message || !negotiated_); @@ -725,10 +967,10 @@ bool SctpDataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { send_params.ordered = ordered_ || is_open_message; send_params.type = DataMessageType::kControl; - RTCError err = controller_->SendData(id_, send_params, buffer); + RTCError err = controller_->SendData(id_n_, send_params, buffer); if (err.ok()) { RTC_DLOG(LS_VERBOSE) << "Sent CONTROL message on channel " - << id_.stream_id_int(); + << id_n_.stream_id_int(); if (handshake_state_ == kHandshakeShouldSendAck) { handshake_state_ = kHandshakeReady; @@ -736,7 +978,7 @@ bool SctpDataChannel::SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) { handshake_state_ = kHandshakeWaitingForAck; } } else if (err.type() == RTCErrorType::RESOURCE_EXHAUSTED) { - QueueControlMessage(buffer); + queued_control_data_.PushBack(std::make_unique(buffer, true)); } else { RTC_LOG(LS_ERROR) << "Closing the DataChannel due to a failure to send" " the CONTROL message, send_result = " @@ -752,10 +994,4 @@ void SctpDataChannel::ResetInternalIdAllocatorForTesting(int new_value) { g_unique_id = new_value; } -SctpDataChannel* DowncastProxiedDataChannelInterfaceToSctpDataChannelForTesting( - DataChannelInterface* channel) { - return static_cast( - static_cast(channel)->internal()); -} - } // namespace webrtc diff --git a/third_party/libwebrtc/pc/sctp_data_channel.h b/third_party/libwebrtc/pc/sctp_data_channel.h index e0f8bb24b645f..13bebd4612e51 100644 --- a/third_party/libwebrtc/pc/sctp_data_channel.h +++ b/third_party/libwebrtc/pc/sctp_data_channel.h @@ -23,6 +23,7 @@ #include "api/rtc_error.h" #include "api/scoped_refptr.h" #include "api/sequence_checker.h" +#include "api/task_queue/pending_task_safety_flag.h" #include "api/transport/data_channel_transport_interface.h" #include "pc/data_channel_utils.h" #include "pc/sctp_utils.h" @@ -38,6 +39,8 @@ namespace webrtc { class SctpDataChannel; +// Interface that acts as a bridge from the data channel to the transport. +// All methods in this interface need to be invoked on the network thread. class SctpDataChannelControllerInterface { public: // Sends the data to the transport. @@ -49,8 +52,6 @@ class SctpDataChannelControllerInterface { // Begins the closing procedure by sending an outgoing stream reset. Still // need to wait for callbacks to tell when this completes. virtual void RemoveSctpDataStream(StreamId sid) = 0; - // Returns true if the transport channel is ready to send data. - virtual bool ReadyToSendData() const = 0; // Notifies the controller of state changes. virtual void OnChannelStateChanged(SctpDataChannel* data_channel, DataChannelInterface::DataState state) = 0; @@ -70,12 +71,17 @@ struct InternalDataChannelInit : public DataChannelInit { bool IsValid() const; OpenHandshakeRole open_handshake_role; + // Optional fallback or backup flag from PC that's used for non-prenegotiated + // stream ids in situations where we cannot determine the SSL role from the + // transport for purposes of generating a stream ID. + // See: https://www.rfc-editor.org/rfc/rfc8832.html#name-protocol-overview + absl::optional fallback_ssl_role; }; // Helper class to allocate unique IDs for SCTP DataChannels. class SctpSidAllocator { public: - SctpSidAllocator(); + SctpSidAllocator() = default; // Gets the first unused odd/even id based on the DTLS role. If `role` is // SSL_CLIENT, the allocated id starts from 0 and takes even numbers; // otherwise, the id starts from 1 and takes odd numbers. @@ -90,7 +96,8 @@ class SctpSidAllocator { private: flat_set used_sids_ RTC_GUARDED_BY(&sequence_checker_); - RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_{ + SequenceChecker::kDetached}; }; // SctpDataChannel is an implementation of the DataChannelInterface based on @@ -129,8 +136,14 @@ class SctpDataChannel : public DataChannelInterface { // Instantiates an API proxy for a SctpDataChannel instance that will be // handed out to external callers. + // The `signaling_safety` flag is used for the ObserverAdapter callback proxy + // which delivers callbacks on the signaling thread but must not deliver such + // callbacks after the peerconnection has been closed. The data controller + // will update the flag when closed, which will cancel any pending event + // notifications. static rtc::scoped_refptr CreateProxy( - rtc::scoped_refptr channel); + rtc::scoped_refptr channel, + rtc::scoped_refptr signaling_safety); void RegisterObserver(DataChannelObserver* observer) override; void UnregisterObserver() override; @@ -159,6 +172,8 @@ class SctpDataChannel : public DataChannelInterface { uint32_t messages_received() const override; uint64_t bytes_received() const override; bool Send(const DataBuffer& buffer) override; + void SendAsync(DataBuffer buffer, + absl::AnyInvocable on_complete) override; // Close immediately, ignoring any queued data or closing procedure. // This is called when the underlying SctpTransport is being destroyed. @@ -167,11 +182,6 @@ class SctpDataChannel : public DataChannelInterface { // Specializations of CloseAbruptlyWithError void CloseAbruptlyWithDataChannelFailure(const std::string& message); - // Slots for controller to connect signals to. - // - // TODO(deadbeef): Make these private once we're hooking up signals ourselves, - // instead of relying on SctpDataChannelControllerInterface. - // Called when the SctpTransport's ready to use. That can happen when we've // finished negotiation, or if the channel was created after negotiation has // already finished. @@ -182,7 +192,7 @@ class SctpDataChannel : public DataChannelInterface { // Sets the SCTP sid and adds to transport layer if not set yet. Should only // be called once. - void SetSctpSid(const StreamId& sid); + void SetSctpSid_n(StreamId sid); // The remote side started the closing procedure by resetting its outgoing // stream (our incoming stream). Sets state to kClosing. @@ -200,7 +210,15 @@ class SctpDataChannel : public DataChannelInterface { DataChannelStats GetStats() const; - const StreamId& sid() const { return id_; } + // Returns a unique identifier that's guaranteed to always be available, + // doesn't change throughout SctpDataChannel's lifetime and is used for + // stats purposes (see also `GetStats()`). + int internal_id() const { return internal_id_; } + + StreamId sid_n() const { + RTC_DCHECK_RUN_ON(network_thread_); + return id_n_; + } // Reset the allocator for internal ID values for testing, so that // the internal IDs generated are predictable. Test only. @@ -216,6 +234,8 @@ class SctpDataChannel : public DataChannelInterface { ~SctpDataChannel() override; private: + class ObserverAdapter; + // The OPEN(_ACK) signaling state. enum HandshakeState { kHandshakeInit, @@ -225,22 +245,29 @@ class SctpDataChannel : public DataChannelInterface { kHandshakeReady }; - void UpdateState(); - void SetState(DataState state); + RTCError SendImpl(DataBuffer buffer) RTC_RUN_ON(network_thread_); + void UpdateState() RTC_RUN_ON(network_thread_); + void SetState(DataState state) RTC_RUN_ON(network_thread_); - void DeliverQueuedReceivedData(); + void DeliverQueuedReceivedData() RTC_RUN_ON(network_thread_); - void SendQueuedDataMessages(); - bool SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked); - bool QueueSendDataMessage(const DataBuffer& buffer); + void SendQueuedDataMessages() RTC_RUN_ON(network_thread_); + RTCError SendDataMessage(const DataBuffer& buffer, bool queue_if_blocked) + RTC_RUN_ON(network_thread_); + bool QueueSendDataMessage(const DataBuffer& buffer) + RTC_RUN_ON(network_thread_); - void SendQueuedControlMessages(); - void QueueControlMessage(const rtc::CopyOnWriteBuffer& buffer); - bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer); + void SendQueuedControlMessages() RTC_RUN_ON(network_thread_); + bool SendControlMessage(const rtc::CopyOnWriteBuffer& buffer) + RTC_RUN_ON(network_thread_); + + bool connected_to_transport() const RTC_RUN_ON(network_thread_) { + return network_safety_->alive(); + } rtc::Thread* const signaling_thread_; rtc::Thread* const network_thread_; - StreamId id_; + StreamId id_n_ RTC_GUARDED_BY(network_thread_); const int internal_id_; const std::string label_; const std::string protocol_; @@ -250,33 +277,29 @@ class SctpDataChannel : public DataChannelInterface { const bool negotiated_; const bool ordered_; - DataChannelObserver* observer_ RTC_GUARDED_BY(signaling_thread_) = nullptr; - DataState state_ RTC_GUARDED_BY(signaling_thread_) = kConnecting; - RTCError error_ RTC_GUARDED_BY(signaling_thread_); - uint32_t messages_sent_ RTC_GUARDED_BY(signaling_thread_) = 0; - uint64_t bytes_sent_ RTC_GUARDED_BY(signaling_thread_) = 0; - uint32_t messages_received_ RTC_GUARDED_BY(signaling_thread_) = 0; - uint64_t bytes_received_ RTC_GUARDED_BY(signaling_thread_) = 0; + DataChannelObserver* observer_ RTC_GUARDED_BY(network_thread_) = nullptr; + std::unique_ptr observer_adapter_; + DataState state_ RTC_GUARDED_BY(network_thread_) = kConnecting; + RTCError error_ RTC_GUARDED_BY(network_thread_); + uint32_t messages_sent_ RTC_GUARDED_BY(network_thread_) = 0; + uint64_t bytes_sent_ RTC_GUARDED_BY(network_thread_) = 0; + uint32_t messages_received_ RTC_GUARDED_BY(network_thread_) = 0; + uint64_t bytes_received_ RTC_GUARDED_BY(network_thread_) = 0; rtc::WeakPtr controller_ - RTC_GUARDED_BY(signaling_thread_); - HandshakeState handshake_state_ RTC_GUARDED_BY(signaling_thread_) = + RTC_GUARDED_BY(network_thread_); + HandshakeState handshake_state_ RTC_GUARDED_BY(network_thread_) = kHandshakeInit; - bool connected_to_transport_ RTC_GUARDED_BY(signaling_thread_) = false; - bool writable_ RTC_GUARDED_BY(signaling_thread_) = false; // Did we already start the graceful SCTP closing procedure? - bool started_closing_procedure_ RTC_GUARDED_BY(signaling_thread_) = false; + bool started_closing_procedure_ RTC_GUARDED_BY(network_thread_) = false; // Control messages that always have to get sent out before any queued // data. - PacketQueue queued_control_data_ RTC_GUARDED_BY(signaling_thread_); - PacketQueue queued_received_data_ RTC_GUARDED_BY(signaling_thread_); - PacketQueue queued_send_data_ RTC_GUARDED_BY(signaling_thread_); + PacketQueue queued_control_data_ RTC_GUARDED_BY(network_thread_); + PacketQueue queued_received_data_ RTC_GUARDED_BY(network_thread_); + PacketQueue queued_send_data_ RTC_GUARDED_BY(network_thread_); + rtc::scoped_refptr network_safety_ = + PendingTaskSafetyFlag::CreateDetachedInactive(); }; -// Downcast a PeerConnectionInterface that points to a proxy object -// to its underlying SctpDataChannel object. For testing only. -SctpDataChannel* DowncastProxiedDataChannelInterfaceToSctpDataChannelForTesting( - DataChannelInterface* channel); - } // namespace webrtc #endif // PC_SCTP_DATA_CHANNEL_H_ diff --git a/third_party/libwebrtc/pc/sdp_offer_answer.cc b/third_party/libwebrtc/pc/sdp_offer_answer.cc index 8dc6d84762b46..0cb10b7d07977 100644 --- a/third_party/libwebrtc/pc/sdp_offer_answer.cc +++ b/third_party/libwebrtc/pc/sdp_offer_answer.cc @@ -815,8 +815,37 @@ bool ContentHasHeaderExtension(const cricket::ContentInfo& content_info, } // namespace +void UpdateRtpHeaderExtensionPreferencesFromSdpMunging( + const cricket::SessionDescription* description, + TransceiverList* transceivers) { + // This integrates the RTP Header Extension Control API and local SDP munging + // for backward compability reasons. If something was enabled in the local + // description via SDP munging, consider it non-stopped in the API as well + // so that is shows up in subsequent offers/answers. + RTC_DCHECK(description); + RTC_DCHECK(transceivers); + for (const auto& content : description->contents()) { + auto transceiver = transceivers->FindByMid(content.name); + if (!transceiver) { + continue; + } + auto extension_capabilities = transceiver->GetHeaderExtensionsToNegotiate(); + // Set the capability of every extension we see here to "sendrecv". + for (auto& ext : content.media_description()->rtp_header_extensions()) { + auto it = absl::c_find_if(extension_capabilities, + [&ext](const RtpHeaderExtensionCapability c) { + return ext.uri == c.uri; + }); + if (it != extension_capabilities.end()) { + it->direction = RtpTransceiverDirection::kSendRecv; + } + } + transceiver->SetHeaderExtensionsToNegotiate(extension_capabilities); + } +} + // This class stores state related to a SetRemoteDescription operation, captures -// and reports potential errors that migth occur and makes sure to notify the +// and reports potential errors that might occur and makes sure to notify the // observer of the operation and the operations chain of completion. class SdpOfferAnswerHandler::RemoteDescriptionOperation { public: @@ -1816,6 +1845,11 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription( local_ice_credentials_to_replace_->ClearIceCredentials(); } + if (IsUnifiedPlan()) { + UpdateRtpHeaderExtensionPreferencesFromSdpMunging( + local_description()->description(), transceivers()); + } + return RTCError::OK(); } @@ -3134,7 +3168,7 @@ void SdpOfferAnswerHandler::OnOperationsChainEmpty() { } } -absl::optional SdpOfferAnswerHandler::is_caller() { +absl::optional SdpOfferAnswerHandler::is_caller() const { RTC_DCHECK_RUN_ON(signaling_thread()); return is_caller_; } @@ -3234,17 +3268,59 @@ void SdpOfferAnswerHandler::AllocateSctpSids() { return; } - absl::optional role = - network_thread()->BlockingCall([this, is_caller = is_caller()] { + absl::optional guessed_role = GuessSslRole(); + network_thread()->BlockingCall( + [&, data_channel_controller = data_channel_controller()] { RTC_DCHECK_RUN_ON(network_thread()); - return pc_->GetSctpSslRole_n(is_caller); + absl::optional role = pc_->GetSctpSslRole_n(); + if (!role) + role = guessed_role; + if (role) + data_channel_controller->AllocateSctpSids(*role); }); +} - if (role) { - // TODO(webrtc:11547): Make this call on the network thread too once - // `AllocateSctpSids` has been updated. - data_channel_controller()->AllocateSctpSids(*role); - } +absl::optional SdpOfferAnswerHandler::GuessSslRole() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + if (!pc_->sctp_mid()) + return absl::nullopt; + + // TODO(bugs.webrtc.org/13668): This guesswork is guessing wrong (returning + // SSL_CLIENT = ACTIVE) if remote offer has role ACTIVE, but we'll be able + // to detect that by looking at the SDP. + // + // The phases of establishing an SCTP session are: + // + // Offerer: + // + // * Before negotiation: Neither is_caller nor sctp_mid exists. + // * After setting an offer as local description: is_caller is known (true), + // sctp_mid is known, but we don't know the SSL role for sure (or if we'll + // eventually get an SCTP session). + // * After setting an answer as the remote description: We know is_caller, + // sctp_mid and that we'll get the SCTP channel established (m-section + // wasn't rejected). + // * Special case: The SCTP m-section was rejected: Close datachannels. + // * We MAY know the SSL role if we offered actpass and got back active or + // passive; if the other end is a webrtc implementation, it will be active. + // * After the TLS handshake: We have a definitive answer on the SSL role. + // + // Answerer: + // + // * After setting an offer as remote description: We know is_caller (false). + // * If there was an SCTP session, we know the SCTP mid. We also know the + // SSL role, since if the remote offer was actpass or passive, we'll answer + // active, and if the remote offer was active, we're passive. + // * Special case: No SCTP m= line. We don't know for sure if the remote + // doesn't support it or just didn't offer it. Not sure what we do in this + // case (logic would suggest fire a `negotiationneeded` event and generate a + // subsequent offer, but this needs to be tested). + // * After the TLS handshake: We know that TLS obeyed the protocol. There + // should be an error surfaced somewhere if it didn't. + // * "Guessing" should always be correct if we get an SCTP session and are not + // the offerer. + + return is_caller() ? rtc::SSL_SERVER : rtc::SSL_CLIENT; } bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() { @@ -3265,9 +3341,21 @@ bool SdpOfferAnswerHandler::CheckIfNegotiationIsNeeded() { // 4. If connection has created any RTCDataChannels, and no m= section in // description has been negotiated yet for data, return true. - if (data_channel_controller()->HasDataChannels()) { - if (!cricket::GetFirstDataContent(description->description()->contents())) + if (data_channel_controller()->HasUsedDataChannels()) { + const cricket::ContentInfo* data_content = + cricket::GetFirstDataContent(description->description()->contents()); + if (!data_content) { + return true; + } + // The remote end might have rejected the data content. + const cricket::ContentInfo* remote_data_content = + current_remote_description() + ? current_remote_description()->description()->GetContentByName( + data_content->name) + : nullptr; + if (remote_data_content && remote_data_content->rejected) { return true; + } } if (!ConfiguredForMedia()) { return false; @@ -3814,14 +3902,9 @@ RTCError SdpOfferAnswerHandler::UpdateDataChannel( RTCError error(RTCErrorType::OPERATION_ERROR_WITH_DATA, sb.Release()); error.set_error_detail(RTCErrorDetailType::DATA_CHANNEL_FAILURE); DestroyDataChannelTransport(error); - } else { - if (!data_channel_controller()->data_channel_transport()) { - RTC_LOG(LS_INFO) << "Creating data channel, mid=" << content.mid(); - if (!CreateDataChannel(content.name)) { - return RTCError(RTCErrorType::INTERNAL_ERROR, - "Failed to create data channel."); - } - } + } else if (!CreateDataChannel(content.name)) { + return RTCError(RTCErrorType::INTERNAL_ERROR, + "Failed to create data channel."); } return RTCError::OK(); } @@ -4192,10 +4275,28 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer( } // Lastly, add a m-section if we have requested local data channels and an // m section does not already exist. - if (!pc_->GetDataMid() && data_channel_controller()->HasUsedDataChannels()) { - session_options->media_description_options.push_back( - GetMediaDescriptionOptionsForActiveData( - mid_generator_.GenerateString())); + if (!pc_->GetDataMid() && data_channel_controller()->HasUsedDataChannels() && + data_channel_controller()->HasDataChannels()) { + // Attempt to recycle a stopped m-line. + // TODO(crbug.com/1442604): GetDataMid() should return the mid if one was + // ever created but rejected. + bool recycled = false; + for (size_t i = 0; i < session_options->media_description_options.size(); + i++) { + auto media_description = session_options->media_description_options[i]; + if (media_description.type == cricket::MEDIA_TYPE_DATA && + media_description.stopped) { + session_options->media_description_options[i] = + GetMediaDescriptionOptionsForActiveData(media_description.mid); + recycled = true; + break; + } + } + if (!recycled) { + session_options->media_description_options.push_back( + GetMediaDescriptionOptionsForActiveData( + mid_generator_.GenerateString())); + } } } @@ -5005,12 +5106,9 @@ RTCError SdpOfferAnswerHandler::CreateChannels(const SessionDescription& desc) { } const cricket::ContentInfo* data = cricket::GetFirstDataContent(&desc); - if (data && !data->rejected && - !data_channel_controller()->data_channel_transport()) { - if (!CreateDataChannel(data->name)) { - return RTCError(RTCErrorType::INTERNAL_ERROR, - "Failed to create data channel."); - } + if (data && !data->rejected && !CreateDataChannel(data->name)) { + return RTCError(RTCErrorType::INTERNAL_ERROR, + "Failed to create data channel."); } return RTCError::OK(); @@ -5018,35 +5116,33 @@ RTCError SdpOfferAnswerHandler::CreateChannels(const SessionDescription& desc) { bool SdpOfferAnswerHandler::CreateDataChannel(const std::string& mid) { RTC_DCHECK_RUN_ON(signaling_thread()); - if (!context_->network_thread()->BlockingCall([this, &mid] { + if (pc_->sctp_mid().has_value()) { + RTC_DCHECK_EQ(mid, *pc_->sctp_mid()); + return true; // data channel already created. + } + + RTC_LOG(LS_INFO) << "Creating data channel, mid=" << mid; + + absl::optional transport_name = + context_->network_thread()->BlockingCall([&] { RTC_DCHECK_RUN_ON(context_->network_thread()); return pc_->SetupDataChannelTransport_n(mid); - })) { + }); + if (!transport_name) return false; - } - // TODO(tommi): Is this necessary? SetupDataChannelTransport_n() above - // will have queued up updating the transport name on the signaling thread - // and could update the mid at the same time. This here is synchronous - // though, but it changes the state of PeerConnection and makes it be - // out of sync (transport name not set while the mid is set). - pc_->SetSctpDataMid(mid); + + pc_->SetSctpDataInfo(mid, *transport_name); return true; } void SdpOfferAnswerHandler::DestroyDataChannelTransport(RTCError error) { RTC_DCHECK_RUN_ON(signaling_thread()); - const bool has_sctp = pc_->sctp_mid().has_value(); - - if (has_sctp) - data_channel_controller()->OnTransportChannelClosed(error); - - context_->network_thread()->BlockingCall([this] { - RTC_DCHECK_RUN_ON(context_->network_thread()); - pc_->TeardownDataChannelTransport_n(); - }); - - if (has_sctp) - pc_->ResetSctpDataMid(); + context_->network_thread()->BlockingCall( + [&, data_channel_controller = data_channel_controller()] { + RTC_DCHECK_RUN_ON(context_->network_thread()); + pc_->TeardownDataChannelTransport_n(error); + }); + pc_->ResetSctpDataInfo(); } void SdpOfferAnswerHandler::DestroyAllChannels() { diff --git a/third_party/libwebrtc/pc/sdp_offer_answer.h b/third_party/libwebrtc/pc/sdp_offer_answer.h index ff075bcb5d130..80a21391b95a3 100644 --- a/third_party/libwebrtc/pc/sdp_offer_answer.h +++ b/third_party/libwebrtc/pc/sdp_offer_answer.h @@ -156,10 +156,15 @@ class SdpOfferAnswerHandler : public SdpStateProvider { bool AddStream(MediaStreamInterface* local_stream); void RemoveStream(MediaStreamInterface* local_stream); - absl::optional is_caller(); + absl::optional is_caller() const; bool HasNewIceCredentials(); void UpdateNegotiationNeeded(); void AllocateSctpSids(); + // Based on the negotiation state, guess what the SSLRole might be without + // directly getting the information from the transport. + // This is used for allocating stream ids for data channels. + // See also `InternalDataChannelInit::fallback_ssl_role`. + absl::optional GuessSslRole() const; // Destroys all BaseChannels and destroys the SCTP data channel, if present. void DestroyAllChannels(); diff --git a/third_party/libwebrtc/pc/sdp_offer_answer_unittest.cc b/third_party/libwebrtc/pc/sdp_offer_answer_unittest.cc index e16cd6aafc93a..4c4554f12cbc1 100644 --- a/third_party/libwebrtc/pc/sdp_offer_answer_unittest.cc +++ b/third_party/libwebrtc/pc/sdp_offer_answer_unittest.cc @@ -20,12 +20,21 @@ #include "api/peer_connection_interface.h" #include "api/rtp_transceiver_interface.h" #include "api/scoped_refptr.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "p2p/base/port_allocator.h" #include "pc/peer_connection_wrapper.h" +#include "pc/session_description.h" #include "pc/test/fake_audio_capture_module.h" #include "pc/test/mock_peer_connection_observers.h" #include "rtc_base/rtc_certificate_generator.h" @@ -59,17 +68,25 @@ class SdpOfferAnswerTest : public ::testing::Test { // Note: We use a PeerConnectionFactory with a distinct // signaling thread, so that thread handling can be tested. : signaling_thread_(CreateAndStartThread()), - pc_factory_( - CreatePeerConnectionFactory(nullptr, - nullptr, - signaling_thread_.get(), - FakeAudioCaptureModule::Create(), - CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory(), - CreateBuiltinVideoEncoderFactory(), - CreateBuiltinVideoDecoderFactory(), - nullptr /* audio_mixer */, - nullptr /* audio_processing */)) { + pc_factory_(CreatePeerConnectionFactory( + nullptr, + nullptr, + signaling_thread_.get(), + FakeAudioCaptureModule::Create(), + CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory(), + std::make_unique< + VideoEncoderFactoryTemplate>(), + std::make_unique< + VideoDecoderFactoryTemplate>(), + nullptr /* audio_mixer */, + nullptr /* audio_processing */)) { webrtc::metrics::Reset(); } @@ -451,4 +468,83 @@ TEST_F(SdpOfferAnswerTest, RollbackPreservesAddTrackMid) { EXPECT_EQ(saved_mid, first_transceiver->mid()); } +#ifdef WEBRTC_HAVE_SCTP + +TEST_F(SdpOfferAnswerTest, RejectedDataChannelsDoNotGetReoffered) { + auto pc = CreatePeerConnection(); + EXPECT_TRUE(pc->pc()->CreateDataChannelOrError("dc", nullptr).ok()); + EXPECT_TRUE(pc->CreateOfferAndSetAsLocal()); + auto mid = pc->pc()->local_description()->description()->contents()[0].mid(); + + // An answer that rejects the datachannel content. + std::string sdp = + "v=0\r\n" + "o=- 4131505339648218884 3 IN IP4 **-----**\r\n" + "s=-\r\n" + "t=0 0\r\n" + "a=ice-ufrag:zGWFZ+fVXDeN6UoI/136\r\n" + "a=ice-pwd:9AUNgUqRNI5LSIrC1qFD2iTR\r\n" + "a=fingerprint:sha-256 " + "AD:52:52:E0:B1:37:34:21:0E:15:8E:B7:56:56:7B:B4:39:0E:6D:1C:F5:84:A7:EE:" + "B5:27:3E:30:B1:7D:69:42\r\n" + "a=setup:passive\r\n" + "m=application 0 UDP/DTLS/SCTP webrtc-datachannel\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=sctp-port:5000\r\n" + "a=max-message-size:262144\r\n" + "a=mid:" + + mid + "\r\n"; + auto answer = CreateSessionDescription(SdpType::kAnswer, sdp); + ASSERT_TRUE(pc->SetRemoteDescription(std::move(answer))); + // The subsequent offer should not recycle the m-line since the existing data + // channel is closed. + auto offer = pc->CreateOffer(); + const auto& offer_contents = offer->description()->contents(); + ASSERT_EQ(offer_contents.size(), 1u); + EXPECT_EQ(offer_contents[0].mid(), mid); + EXPECT_EQ(offer_contents[0].rejected, true); +} + +TEST_F(SdpOfferAnswerTest, RejectedDataChannelsDoGetReofferedWhenActive) { + auto pc = CreatePeerConnection(); + EXPECT_TRUE(pc->pc()->CreateDataChannelOrError("dc", nullptr).ok()); + EXPECT_TRUE(pc->CreateOfferAndSetAsLocal()); + auto mid = pc->pc()->local_description()->description()->contents()[0].mid(); + + // An answer that rejects the datachannel content. + std::string sdp = + "v=0\r\n" + "o=- 4131505339648218884 3 IN IP4 **-----**\r\n" + "s=-\r\n" + "t=0 0\r\n" + "a=ice-ufrag:zGWFZ+fVXDeN6UoI/136\r\n" + "a=ice-pwd:9AUNgUqRNI5LSIrC1qFD2iTR\r\n" + "a=fingerprint:sha-256 " + "AD:52:52:E0:B1:37:34:21:0E:15:8E:B7:56:56:7B:B4:39:0E:6D:1C:F5:84:A7:EE:" + "B5:27:3E:30:B1:7D:69:42\r\n" + "a=setup:passive\r\n" + "m=application 0 UDP/DTLS/SCTP webrtc-datachannel\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=sctp-port:5000\r\n" + "a=max-message-size:262144\r\n" + "a=mid:" + + mid + "\r\n"; + auto answer = CreateSessionDescription(SdpType::kAnswer, sdp); + ASSERT_TRUE(pc->SetRemoteDescription(std::move(answer))); + + // The subsequent offer should recycle the m-line when there is a new data + // channel. + EXPECT_TRUE(pc->pc()->CreateDataChannelOrError("dc2", nullptr).ok()); + EXPECT_TRUE(pc->pc()->ShouldFireNegotiationNeededEvent( + pc->observer()->latest_negotiation_needed_event())); + + auto offer = pc->CreateOffer(); + const auto& offer_contents = offer->description()->contents(); + ASSERT_EQ(offer_contents.size(), 1u); + EXPECT_EQ(offer_contents[0].mid(), mid); + EXPECT_EQ(offer_contents[0].rejected, false); +} + +#endif // WEBRTC_HAVE_SCTP + } // namespace webrtc diff --git a/third_party/libwebrtc/pc/slow_peer_connection_integration_test.cc b/third_party/libwebrtc/pc/slow_peer_connection_integration_test.cc index 004b79515bd97..fd9d3417dfeba 100644 --- a/third_party/libwebrtc/pc/slow_peer_connection_integration_test.cc +++ b/third_party/libwebrtc/pc/slow_peer_connection_integration_test.cc @@ -67,7 +67,7 @@ class FakeClockForTest : public rtc::ScopedFakeClock { // Some things use a time of "0" as a special value, so we need to start out // the fake clock at a nonzero time. // TODO(deadbeef): Fix this. - AdvanceTime(webrtc::TimeDelta::Seconds(1)); + AdvanceTime(webrtc::TimeDelta::Seconds(1000)); } // Explicit handle. diff --git a/third_party/libwebrtc/pc/test/fake_audio_capture_module.cc b/third_party/libwebrtc/pc/test/fake_audio_capture_module.cc index 132328291c511..6ffa18c886763 100644 --- a/third_party/libwebrtc/pc/test/fake_audio_capture_module.cc +++ b/third_party/libwebrtc/pc/test/fake_audio_capture_module.cc @@ -44,9 +44,7 @@ FakeAudioCaptureModule::FakeAudioCaptureModule() current_mic_level_(kMaxVolume), started_(false), next_frame_time_(0), - frames_received_(0) { - process_thread_checker_.Detach(); -} + frames_received_(0) {} FakeAudioCaptureModule::~FakeAudioCaptureModule() { if (process_thread_) { diff --git a/third_party/libwebrtc/pc/test/fake_audio_capture_module.h b/third_party/libwebrtc/pc/test/fake_audio_capture_module.h index 84ddacb26fa96..c04373cdfdd4e 100644 --- a/third_party/libwebrtc/pc/test/fake_audio_capture_module.h +++ b/third_party/libwebrtc/pc/test/fake_audio_capture_module.h @@ -229,7 +229,8 @@ class FakeAudioCaptureModule : public webrtc::AudioDeviceModule { // Protects variables that are accessed from process_thread_ and // the main thread. mutable webrtc::Mutex mutex_; - webrtc::SequenceChecker process_thread_checker_; + webrtc::SequenceChecker process_thread_checker_{ + webrtc::SequenceChecker::kDetached}; }; #endif // PC_TEST_FAKE_AUDIO_CAPTURE_MODULE_H_ diff --git a/third_party/libwebrtc/pc/test/fake_data_channel_controller.h b/third_party/libwebrtc/pc/test/fake_data_channel_controller.h index c9775e02a1d0a..c489a3432458e 100644 --- a/third_party/libwebrtc/pc/test/fake_data_channel_controller.h +++ b/third_party/libwebrtc/pc/test/fake_data_channel_controller.h @@ -13,6 +13,7 @@ #include #include +#include #include "pc/sctp_data_channel.h" #include "rtc_base/checks.h" @@ -21,42 +22,64 @@ class FakeDataChannelController : public webrtc::SctpDataChannelControllerInterface { public: - FakeDataChannelController() - : send_blocked_(false), + explicit FakeDataChannelController(rtc::Thread* network_thread) + : signaling_thread_(rtc::Thread::Current()), + network_thread_(network_thread), + send_blocked_(false), transport_available_(false), ready_to_send_(false), transport_error_(false) {} - virtual ~FakeDataChannelController() {} + + ~FakeDataChannelController() override { + network_thread_->BlockingCall([&] { + RTC_DCHECK_RUN_ON(network_thread_); + weak_factory_.InvalidateWeakPtrs(); + }); + } rtc::WeakPtr weak_ptr() { + RTC_DCHECK_RUN_ON(network_thread_); return weak_factory_.GetWeakPtr(); } rtc::scoped_refptr CreateDataChannel( absl::string_view label, - webrtc::InternalDataChannelInit init, - rtc::Thread* network_thread = rtc::Thread::Current()) { - rtc::Thread* signaling_thread = rtc::Thread::Current(); + webrtc::InternalDataChannelInit init) { rtc::scoped_refptr channel = - webrtc::SctpDataChannel::Create(weak_ptr(), std::string(label), - transport_available_, init, - signaling_thread, network_thread); - if (ReadyToSendData()) { - signaling_thread->PostTask( - SafeTask(signaling_safety_.flag(), [channel = channel] { - if (channel->state() != - webrtc::DataChannelInterface::DataState::kClosed) { - channel->OnTransportReady(); - } - })); - } - connected_channels_.insert(channel.get()); + network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + rtc::WeakPtr my_weak_ptr = weak_ptr(); + // Explicitly associate the weak ptr instance with the current thread + // to catch early any inappropriate referencing of it on the network + // thread. + RTC_CHECK(my_weak_ptr); + + rtc::scoped_refptr channel = + webrtc::SctpDataChannel::Create( + std::move(my_weak_ptr), std::string(label), + transport_available_, init, signaling_thread_, + network_thread_); + if (transport_available_ && channel->sid_n().HasValue()) { + AddSctpDataStream(channel->sid_n()); + } + if (ready_to_send_) { + network_thread_->PostTask([channel = channel] { + if (channel->state() != + webrtc::DataChannelInterface::DataState::kClosed) { + channel->OnTransportReady(); + } + }); + } + connected_channels_.insert(channel.get()); + return channel; + }); return channel; } webrtc::RTCError SendData(webrtc::StreamId sid, const webrtc::SendDataParams& params, const rtc::CopyOnWriteBuffer& payload) override { + RTC_DCHECK_RUN_ON(network_thread_); RTC_CHECK(ready_to_send_); RTC_CHECK(transport_available_); if (send_blocked_) { @@ -67,12 +90,13 @@ class FakeDataChannelController return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR); } - last_sid_ = sid.stream_id_int(); + last_sid_ = sid; last_send_data_params_ = params; return webrtc::RTCError::OK(); } void AddSctpDataStream(webrtc::StreamId sid) override { + RTC_DCHECK_RUN_ON(network_thread_); RTC_CHECK(sid.HasValue()); if (!transport_available_) { return; @@ -81,23 +105,23 @@ class FakeDataChannelController } void RemoveSctpDataStream(webrtc::StreamId sid) override { + RTC_DCHECK_RUN_ON(network_thread_); RTC_CHECK(sid.HasValue()); known_stream_ids_.erase(sid); // Unlike the real SCTP transport, act like the closing procedure finished - // instantly, doing the same snapshot thing as below. + // instantly. auto it = absl::c_find_if(connected_channels_, - [&](const auto* c) { return c->sid() == sid; }); + [&](const auto* c) { return c->sid_n() == sid; }); // This path mimics the DCC's OnChannelClosed handler since the FDCC // (this class) doesn't have a transport that would do that. if (it != connected_channels_.end()) (*it)->OnClosingProcedureComplete(); } - bool ReadyToSendData() const override { return ready_to_send_; } - void OnChannelStateChanged( webrtc::SctpDataChannel* data_channel, webrtc::DataChannelInterface::DataState state) override { + RTC_DCHECK_RUN_ON(network_thread_); if (state == webrtc::DataChannelInterface::DataState::kOpen) { ++channels_opened_; } else if (state == webrtc::DataChannelInterface::DataState::kClosed) { @@ -108,68 +132,107 @@ class FakeDataChannelController // Set true to emulate the SCTP stream being blocked by congestion control. void set_send_blocked(bool blocked) { - send_blocked_ = blocked; - if (!blocked) { - RTC_CHECK(transport_available_); - // Make a copy since `connected_channels_` may change while - // OnTransportReady is called. - auto copy = connected_channels_; - for (webrtc::SctpDataChannel* ch : copy) { - ch->OnTransportReady(); + network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + send_blocked_ = blocked; + if (!blocked) { + RTC_CHECK(transport_available_); + // Make a copy since `connected_channels_` may change while + // OnTransportReady is called. + auto copy = connected_channels_; + for (webrtc::SctpDataChannel* ch : copy) { + ch->OnTransportReady(); + } } - } + }); } // Set true to emulate the transport channel creation, e.g. after // setLocalDescription/setRemoteDescription called with data content. void set_transport_available(bool available) { - transport_available_ = available; + network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + transport_available_ = available; + }); } - // Set true to emulate the transport ReadyToSendData signal when the transport - // becomes writable for the first time. + // Set true to emulate the transport OnTransportReady signal when the + // transport becomes writable for the first time. void set_ready_to_send(bool ready) { - RTC_CHECK(transport_available_); - ready_to_send_ = ready; - if (ready) { - std::set::iterator it; - for (it = connected_channels_.begin(); it != connected_channels_.end(); - ++it) { - (*it)->OnTransportReady(); + network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + RTC_CHECK(transport_available_); + ready_to_send_ = ready; + if (ready) { + std::set::iterator it; + for (it = connected_channels_.begin(); it != connected_channels_.end(); + ++it) { + (*it)->OnTransportReady(); + } } - } + }); } - void set_transport_error() { transport_error_ = true; } + void set_transport_error() { + network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + transport_error_ = true; + }); + } - int last_sid() const { return last_sid_; } - const webrtc::SendDataParams& last_send_data_params() const { - return last_send_data_params_; + int last_sid() const { + return network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + return last_sid_.stream_id_int(); + }); + } + + webrtc::SendDataParams last_send_data_params() const { + return network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + return last_send_data_params_; + }); } bool IsConnected(webrtc::SctpDataChannel* data_channel) const { - return connected_channels_.find(data_channel) != connected_channels_.end(); + return network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + return connected_channels_.find(data_channel) != + connected_channels_.end(); + }); } bool IsStreamAdded(webrtc::StreamId id) const { - return known_stream_ids_.find(id) != known_stream_ids_.end(); + return network_thread_->BlockingCall([&]() { + RTC_DCHECK_RUN_ON(network_thread_); + return known_stream_ids_.find(id) != known_stream_ids_.end(); + }); } - int channels_opened() const { return channels_opened_; } - int channels_closed() const { return channels_closed_; } + int channels_opened() const { + RTC_DCHECK_RUN_ON(network_thread_); + return channels_opened_; + } + int channels_closed() const { + RTC_DCHECK_RUN_ON(network_thread_); + return channels_closed_; + } private: - int last_sid_; - webrtc::SendDataParams last_send_data_params_; - bool send_blocked_; - bool transport_available_; - bool ready_to_send_; - bool transport_error_; - int channels_closed_ = 0; - int channels_opened_ = 0; - std::set connected_channels_; - std::set known_stream_ids_; - rtc::WeakPtrFactory weak_factory_{this}; - webrtc::ScopedTaskSafety signaling_safety_; + rtc::Thread* const signaling_thread_; + rtc::Thread* const network_thread_; + webrtc::StreamId last_sid_ RTC_GUARDED_BY(network_thread_); + webrtc::SendDataParams last_send_data_params_ RTC_GUARDED_BY(network_thread_); + bool send_blocked_ RTC_GUARDED_BY(network_thread_); + bool transport_available_ RTC_GUARDED_BY(network_thread_); + bool ready_to_send_ RTC_GUARDED_BY(network_thread_); + bool transport_error_ RTC_GUARDED_BY(network_thread_); + int channels_closed_ RTC_GUARDED_BY(network_thread_) = 0; + int channels_opened_ RTC_GUARDED_BY(network_thread_) = 0; + std::set connected_channels_ + RTC_GUARDED_BY(network_thread_); + std::set known_stream_ids_ RTC_GUARDED_BY(network_thread_); + rtc::WeakPtrFactory weak_factory_ + RTC_GUARDED_BY(network_thread_){this}; }; #endif // PC_TEST_FAKE_DATA_CHANNEL_CONTROLLER_H_ diff --git a/third_party/libwebrtc/pc/test/fake_peer_connection_base.h b/third_party/libwebrtc/pc/test/fake_peer_connection_base.h index 69b0106d1f21f..743c18122a30d 100644 --- a/third_party/libwebrtc/pc/test/fake_peer_connection_base.h +++ b/third_party/libwebrtc/pc/test/fake_peer_connection_base.h @@ -320,9 +320,7 @@ class FakePeerConnectionBase : public PeerConnectionInternal { cricket::PortAllocator* port_allocator() override { return nullptr; } LegacyStatsCollector* legacy_stats() override { return nullptr; } PeerConnectionObserver* Observer() const override { return nullptr; } - bool GetSctpSslRole(rtc::SSLRole* role) override { return false; } - absl::optional GetSctpSslRole_n( - absl::optional is_caller) override { + absl::optional GetSctpSslRole_n() override { return absl::nullopt; } PeerConnectionInterface::IceConnectionState ice_connection_state_internal() @@ -360,12 +358,14 @@ class FakePeerConnectionBase : public PeerConnectionInternal { Call* call_ptr() override { return nullptr; } bool SrtpRequired() const override { return false; } - bool SetupDataChannelTransport_n(const std::string& mid) override { - return false; + absl::optional SetupDataChannelTransport_n( + absl::string_view mid) override { + return absl::nullopt; } - void TeardownDataChannelTransport_n() override {} - void SetSctpDataMid(const std::string& mid) override {} - void ResetSctpDataMid() override {} + void TeardownDataChannelTransport_n(RTCError error) override {} + void SetSctpDataInfo(absl::string_view mid, + absl::string_view transport_name) override {} + void ResetSctpDataInfo() override {} const FieldTrialsView& trials() const override { return field_trials_; } diff --git a/third_party/libwebrtc/pc/test/fake_peer_connection_for_stats.h b/third_party/libwebrtc/pc/test/fake_peer_connection_for_stats.h index ca3aa5c94f4a3..79be6a04036cb 100644 --- a/third_party/libwebrtc/pc/test/fake_peer_connection_for_stats.h +++ b/third_party/libwebrtc/pc/test/fake_peer_connection_for_stats.h @@ -205,7 +205,8 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase { dependencies_(MakeDependencies()), context_(ConnectionContext::Create(&dependencies_)), local_streams_(StreamCollection::Create()), - remote_streams_(StreamCollection::Create()) {} + remote_streams_(StreamCollection::Create()), + data_channel_controller_(network_thread_) {} ~FakePeerConnectionForStats() { for (auto transceiver : transceivers_) { diff --git a/third_party/libwebrtc/pc/test/fake_periodic_video_source.h b/third_party/libwebrtc/pc/test/fake_periodic_video_source.h index 871c29cbaeca6..452a8f6c30b84 100644 --- a/third_party/libwebrtc/pc/test/fake_periodic_video_source.h +++ b/third_party/libwebrtc/pc/test/fake_periodic_video_source.h @@ -46,18 +46,18 @@ class FakePeriodicVideoSource final config.timestamp_offset_ms * rtc::kNumMicrosecsPerMillisec), task_queue_(std::make_unique( "FakePeriodicVideoTrackSource")) { - thread_checker_.Detach(); frame_source_.SetRotation(config.rotation); TimeDelta frame_interval = TimeDelta::Millis(config.frame_interval_ms); - RepeatingTaskHandle::Start(task_queue_->Get(), [this, frame_interval] { - if (broadcaster_.wants().rotation_applied) { - broadcaster_.OnFrame(frame_source_.GetFrameRotationApplied()); - } else { - broadcaster_.OnFrame(frame_source_.GetFrame()); - } - return frame_interval; - }); + repeating_task_handle_ = + RepeatingTaskHandle::Start(task_queue_->Get(), [this, frame_interval] { + if (broadcaster_.wants().rotation_applied) { + broadcaster_.OnFrame(frame_source_.GetFrameRotationApplied()); + } else { + broadcaster_.OnFrame(frame_source_.GetFrame()); + } + return frame_interval; + }); } rtc::VideoSinkWants wants() const { @@ -82,11 +82,12 @@ class FakePeriodicVideoSource final void Stop() { RTC_DCHECK(task_queue_); + task_queue_->SendTask([&]() { repeating_task_handle_.Stop(); }); task_queue_.reset(); } private: - SequenceChecker thread_checker_; + SequenceChecker thread_checker_{SequenceChecker::kDetached}; rtc::VideoBroadcaster broadcaster_; cricket::FakeFrameSource frame_source_; @@ -94,6 +95,7 @@ class FakePeriodicVideoSource final rtc::VideoSinkWants wants_ RTC_GUARDED_BY(&mutex_); std::unique_ptr task_queue_; + RepeatingTaskHandle repeating_task_handle_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/pc/test/fake_periodic_video_track_source.h b/third_party/libwebrtc/pc/test/fake_periodic_video_track_source.h index 98a456f2328c1..f91144d1cc5f8 100644 --- a/third_party/libwebrtc/pc/test/fake_periodic_video_track_source.h +++ b/third_party/libwebrtc/pc/test/fake_periodic_video_track_source.h @@ -29,6 +29,7 @@ class FakePeriodicVideoTrackSource : public VideoTrackSource { ~FakePeriodicVideoTrackSource() = default; + FakePeriodicVideoSource& fake_periodic_source() { return source_; } const FakePeriodicVideoSource& fake_periodic_source() const { return source_; } diff --git a/third_party/libwebrtc/pc/test/integration_test_helpers.cc b/third_party/libwebrtc/pc/test/integration_test_helpers.cc index 911ce3f2639fa..3f07c9e8267c5 100644 --- a/third_party/libwebrtc/pc/test/integration_test_helpers.cc +++ b/third_party/libwebrtc/pc/test/integration_test_helpers.cc @@ -56,9 +56,7 @@ int FindFirstMediaStatsIndexByKind( } TaskQueueMetronome::TaskQueueMetronome(TimeDelta tick_period) - : tick_period_(tick_period) { - sequence_checker_.Detach(); -} + : tick_period_(tick_period) {} TaskQueueMetronome::~TaskQueueMetronome() { RTC_DCHECK_RUN_ON(&sequence_checker_); diff --git a/third_party/libwebrtc/pc/test/integration_test_helpers.h b/third_party/libwebrtc/pc/test/integration_test_helpers.h index 200a025ca5234..8cf18ce2f0c95 100644 --- a/third_party/libwebrtc/pc/test/integration_test_helpers.h +++ b/third_party/libwebrtc/pc/test/integration_test_helpers.h @@ -186,7 +186,7 @@ class TaskQueueMetronome : public webrtc::Metronome { private: const TimeDelta tick_period_; - SequenceChecker sequence_checker_; + SequenceChecker sequence_checker_{SequenceChecker::kDetached}; std::vector> callbacks_; ScopedTaskSafetyDetached safety_; }; diff --git a/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h b/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h index a3ee7d8933f58..58d13ede2f6a8 100644 --- a/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h +++ b/third_party/libwebrtc/pc/test/mock_peer_connection_internal.h @@ -231,11 +231,7 @@ class MockPeerConnectionInternal : public PeerConnectionInternal { MOCK_METHOD(cricket::PortAllocator*, port_allocator, (), (override)); MOCK_METHOD(LegacyStatsCollector*, legacy_stats, (), (override)); MOCK_METHOD(PeerConnectionObserver*, Observer, (), (const, override)); - MOCK_METHOD(bool, GetSctpSslRole, (rtc::SSLRole*), (override)); - MOCK_METHOD(absl::optional, - GetSctpSslRole_n, - (absl::optional), - (override)); + MOCK_METHOD(absl::optional, GetSctpSslRole_n, (), (override)); MOCK_METHOD(PeerConnectionInterface::IceConnectionState, ice_connection_state_internal, (), @@ -267,13 +263,16 @@ class MockPeerConnectionInternal : public PeerConnectionInternal { (override)); MOCK_METHOD(Call*, call_ptr, (), (override)); MOCK_METHOD(bool, SrtpRequired, (), (const, override)); - MOCK_METHOD(bool, + MOCK_METHOD(absl::optional, SetupDataChannelTransport_n, - (const std::string&), + (absl::string_view mid), + (override)); + MOCK_METHOD(void, TeardownDataChannelTransport_n, (RTCError), (override)); + MOCK_METHOD(void, + SetSctpDataInfo, + (absl::string_view, absl::string_view), (override)); - MOCK_METHOD(void, TeardownDataChannelTransport_n, (), (override)); - MOCK_METHOD(void, SetSctpDataMid, (const std::string&), (override)); - MOCK_METHOD(void, ResetSctpDataMid, (), (override)); + MOCK_METHOD(void, ResetSctpDataInfo, (), (override)); MOCK_METHOD(const FieldTrialsView&, trials, (), (const, override)); // PeerConnectionInternal @@ -323,7 +322,7 @@ class MockPeerConnectionInternal : public PeerConnectionInternal { MOCK_METHOD(void, NoteDataAddedEvent, (), (override)); MOCK_METHOD(void, OnSctpDataChannelStateChanged, - (DataChannelInterface * channel, DataChannelInterface::DataState), + (int channel_id, DataChannelInterface::DataState), (override)); }; diff --git a/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.cc b/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.cc index 84a01f4438f80..112f04d66bd94 100644 --- a/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.cc +++ b/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.cc @@ -21,16 +21,24 @@ #include "api/audio/audio_mixer.h" #include "api/create_peerconnection_factory.h" #include "api/sequence_checker.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/video_decoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" #include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" +#include "media/engine/simulcast_encoder_adapter.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" #include "p2p/base/fake_port_allocator.h" #include "p2p/base/port_allocator.h" #include "pc/test/fake_periodic_video_source.h" -#include "pc/test/fake_periodic_video_track_source.h" #include "pc/test/fake_rtc_certificate_generator.h" #include "pc/test/mock_peer_connection_observers.h" #include "rtc_base/gunit.h" @@ -58,6 +66,38 @@ const char kAudioTrackLabelBase[] = "audio_track"; constexpr int kMaxWait = 10000; constexpr int kTestAudioFrameCount = 3; constexpr int kTestVideoFrameCount = 3; + +class FuzzyMatchedVideoEncoderFactory : public webrtc::VideoEncoderFactory { + public: + std::vector GetSupportedFormats() const override { + return factory_.GetSupportedFormats(); + } + + std::unique_ptr CreateVideoEncoder( + const webrtc::SdpVideoFormat& format) override { + if (absl::optional original_format = + webrtc::FuzzyMatchSdpVideoFormat(factory_.GetSupportedFormats(), + format)) { + return std::make_unique( + &factory_, *original_format); + } + + return nullptr; + } + + CodecSupport QueryCodecSupport( + const webrtc::SdpVideoFormat& format, + absl::optional scalability_mode) const override { + return factory_.QueryCodecSupport(format, scalability_mode); + } + + private: + webrtc::VideoEncoderFactoryTemplate + factory_; +}; } // namespace void PeerConnectionTestWrapper::Connect(PeerConnectionTestWrapper* caller, @@ -88,6 +128,9 @@ PeerConnectionTestWrapper::PeerConnectionTestWrapper( PeerConnectionTestWrapper::~PeerConnectionTestWrapper() { RTC_DCHECK_RUN_ON(&pc_thread_checker_); + // To avoid flaky bot failures, make sure fake sources are stopped prior to + // closing the peer connections. See https://crbug.com/webrtc/15018. + StopFakeVideoSources(); // Either network_thread or worker_thread might be active at this point. // Relying on ~PeerConnection to properly wait for them doesn't work, // as a vptr race might occur (before we enter the destruction body). @@ -118,9 +161,13 @@ bool PeerConnectionTestWrapper::CreatePc( network_thread_, worker_thread_, rtc::Thread::Current(), rtc::scoped_refptr(fake_audio_capture_module_), audio_encoder_factory, audio_decoder_factory, - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + std::make_unique(), + std::make_unique>(), + nullptr /* audio_mixer */, nullptr /* audio_processing */); if (!peer_connection_factory_) { return false; } @@ -347,6 +394,7 @@ PeerConnectionTestWrapper::GetUserMedia( auto source = rtc::make_ref_counted( config, /* remote */ false); + fake_video_sources_.push_back(source); std::string videotrack_label = stream_id + kVideoTrackLabelBase; rtc::scoped_refptr video_track( @@ -356,3 +404,10 @@ PeerConnectionTestWrapper::GetUserMedia( } return stream; } + +void PeerConnectionTestWrapper::StopFakeVideoSources() { + for (const auto& fake_video_source : fake_video_sources_) { + fake_video_source->fake_periodic_source().Stop(); + } + fake_video_sources_.clear(); +} diff --git a/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.h b/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.h index 23a6996c30ee5..cfc423f81ab65 100644 --- a/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.h +++ b/third_party/libwebrtc/pc/test/peer_connection_test_wrapper.h @@ -29,6 +29,7 @@ #include "api/video/resolution.h" #include "pc/test/fake_audio_capture_module.h" #include "pc/test/fake_periodic_video_source.h" +#include "pc/test/fake_periodic_video_track_source.h" #include "pc/test/fake_video_track_renderer.h" #include "rtc_base/third_party/sigslot/sigslot.h" #include "rtc_base/thread.h" @@ -115,6 +116,7 @@ class PeerConnectionTestWrapper webrtc::Resolution resolution = { .width = webrtc::FakePeriodicVideoSource::kDefaultWidth, .height = webrtc::FakePeriodicVideoSource::kDefaultHeight}); + void StopFakeVideoSources(); private: void SetLocalDescription(webrtc::SdpType type, const std::string& sdp); @@ -136,6 +138,8 @@ class PeerConnectionTestWrapper std::unique_ptr renderer_; int num_get_user_media_calls_ = 0; bool pending_negotiation_; + std::vector> + fake_video_sources_; }; #endif // PC_TEST_PEER_CONNECTION_TEST_WRAPPER_H_ diff --git a/third_party/libwebrtc/pc/test/rtp_transport_test_util.h b/third_party/libwebrtc/pc/test/rtp_transport_test_util.h index 0353b74754379..e93dbdb3c2b90 100644 --- a/third_party/libwebrtc/pc/test/rtp_transport_test_util.h +++ b/third_party/libwebrtc/pc/test/rtp_transport_test_util.h @@ -30,6 +30,8 @@ class TransportObserver : public RtpPacketSinkInterface, this, &TransportObserver::OnRtcpPacketReceived); rtp_transport->SignalReadyToSend.connect(this, &TransportObserver::OnReadyToSend); + rtp_transport->SignalUnDemuxableRtpPacketReceived.connect( + this, &TransportObserver::OnUndemuxableRtpPacket); } // RtpPacketInterface override. @@ -38,6 +40,10 @@ class TransportObserver : public RtpPacketSinkInterface, last_recv_rtp_packet_ = packet.Buffer(); } + void OnUndemuxableRtpPacket(const RtpPacketReceived& packet) { + un_demuxable_rtp_count_++; + } + void OnRtcpPacketReceived(rtc::CopyOnWriteBuffer* packet, int64_t packet_time_us) { rtcp_count_++; @@ -45,6 +51,7 @@ class TransportObserver : public RtpPacketSinkInterface, } int rtp_count() const { return rtp_count_; } + int un_demuxable_rtp_count() const { return un_demuxable_rtp_count_; } int rtcp_count() const { return rtcp_count_; } rtc::CopyOnWriteBuffer last_recv_rtp_packet() { @@ -67,6 +74,7 @@ class TransportObserver : public RtpPacketSinkInterface, private: bool ready_to_send_ = false; int rtp_count_ = 0; + int un_demuxable_rtp_count_ = 0; int rtcp_count_ = 0; int ready_to_send_signal_count_ = 0; rtc::CopyOnWriteBuffer last_recv_rtp_packet_; diff --git a/third_party/libwebrtc/pc/test/simulcast_layer_util.cc b/third_party/libwebrtc/pc/test/simulcast_layer_util.cc new file mode 100644 index 0000000000000..6ce09b5e9b392 --- /dev/null +++ b/third_party/libwebrtc/pc/test/simulcast_layer_util.cc @@ -0,0 +1,55 @@ +/* + * 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 "pc/test/simulcast_layer_util.h" + +#include "absl/algorithm/container.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +std::vector CreateLayers( + const std::vector& rids, + const std::vector& active) { + RTC_DCHECK_EQ(rids.size(), active.size()); + std::vector result; + absl::c_transform(rids, active, std::back_inserter(result), + [](const std::string& rid, bool is_active) { + return cricket::SimulcastLayer(rid, !is_active); + }); + return result; +} + +std::vector CreateLayers( + const std::vector& rids, + bool active) { + return CreateLayers(rids, std::vector(rids.size(), active)); +} + +RtpTransceiverInit CreateTransceiverInit( + const std::vector& layers) { + RtpTransceiverInit init; + for (const cricket::SimulcastLayer& layer : layers) { + RtpEncodingParameters encoding; + encoding.rid = layer.rid; + encoding.active = !layer.is_paused; + init.send_encodings.push_back(encoding); + } + return init; +} + +cricket::SimulcastDescription RemoveSimulcast(SessionDescriptionInterface* sd) { + auto mcd = sd->description()->contents()[0].media_description(); + auto result = mcd->simulcast_description(); + mcd->set_simulcast_description(cricket::SimulcastDescription()); + return result; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/pc/test/simulcast_layer_util.h b/third_party/libwebrtc/pc/test/simulcast_layer_util.h new file mode 100644 index 0000000000000..6822e3c9fd9f2 --- /dev/null +++ b/third_party/libwebrtc/pc/test/simulcast_layer_util.h @@ -0,0 +1,39 @@ +/* + * 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 PC_TEST_SIMULCAST_LAYER_UTIL_H_ +#define PC_TEST_SIMULCAST_LAYER_UTIL_H_ + +#include +#include + +#include "api/jsep.h" +#include "api/rtp_transceiver_interface.h" +#include "pc/session_description.h" +#include "pc/simulcast_description.h" + +namespace webrtc { + +std::vector CreateLayers( + const std::vector& rids, + const std::vector& active); + +std::vector CreateLayers( + const std::vector& rids, + bool active); + +RtpTransceiverInit CreateTransceiverInit( + const std::vector& layers); + +cricket::SimulcastDescription RemoveSimulcast(SessionDescriptionInterface* sd); + +} // namespace webrtc + +#endif // PC_TEST_SIMULCAST_LAYER_UTIL_H_ diff --git a/third_party/libwebrtc/pc/video_rtp_track_source.cc b/third_party/libwebrtc/pc/video_rtp_track_source.cc index bcfcdcbdf9c8a..e4b333c7c2b2f 100644 --- a/third_party/libwebrtc/pc/video_rtp_track_source.cc +++ b/third_party/libwebrtc/pc/video_rtp_track_source.cc @@ -19,9 +19,7 @@ namespace webrtc { VideoRtpTrackSource::VideoRtpTrackSource(Callback* callback) - : VideoTrackSource(true /* remote */), callback_(callback) { - worker_sequence_checker_.Detach(); -} + : VideoTrackSource(true /* remote */), callback_(callback) {} void VideoRtpTrackSource::ClearCallback() { RTC_DCHECK_RUN_ON(&worker_sequence_checker_); diff --git a/third_party/libwebrtc/pc/video_rtp_track_source.h b/third_party/libwebrtc/pc/video_rtp_track_source.h index a9e43f6667527..bf7da99f98ec4 100644 --- a/third_party/libwebrtc/pc/video_rtp_track_source.h +++ b/third_party/libwebrtc/pc/video_rtp_track_source.h @@ -76,7 +76,8 @@ class VideoRtpTrackSource : public VideoTrackSource { rtc::VideoSinkInterface* sink) override; private: - RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_{ + SequenceChecker::kDetached}; // `broadcaster_` is needed since the decoder can only handle one sink. // It might be better if the decoder can handle multiple sinks and consider // the VideoSinkWants. diff --git a/third_party/libwebrtc/pc/video_track_source.cc b/third_party/libwebrtc/pc/video_track_source.cc index 64e99cc064c3f..d4b7f55055735 100644 --- a/third_party/libwebrtc/pc/video_track_source.cc +++ b/third_party/libwebrtc/pc/video_track_source.cc @@ -15,9 +15,7 @@ namespace webrtc { VideoTrackSource::VideoTrackSource(bool remote) - : state_(kInitializing), remote_(remote) { - worker_thread_checker_.Detach(); -} + : state_(kInitializing), remote_(remote) {} void VideoTrackSource::SetState(SourceState new_state) { RTC_DCHECK_RUN_ON(&signaling_thread_checker_); diff --git a/third_party/libwebrtc/pc/video_track_source.h b/third_party/libwebrtc/pc/video_track_source.h index 723b10d8f3cd8..6aae178f37968 100644 --- a/third_party/libwebrtc/pc/video_track_source.h +++ b/third_party/libwebrtc/pc/video_track_source.h @@ -62,7 +62,8 @@ class RTC_EXPORT VideoTrackSource : public Notifier { virtual rtc::VideoSourceInterface* source() = 0; private: - RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_; + RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_thread_checker_{ + SequenceChecker::kDetached}; RTC_NO_UNIQUE_ADDRESS SequenceChecker signaling_thread_checker_; SourceState state_ RTC_GUARDED_BY(&signaling_thread_checker_); const bool remote_; diff --git a/third_party/libwebrtc/pc/webrtc_sdp.cc b/third_party/libwebrtc/pc/webrtc_sdp.cc index 6d041ff0a1c8c..4beb6b0faa0eb 100644 --- a/third_party/libwebrtc/pc/webrtc_sdp.cc +++ b/third_party/libwebrtc/pc/webrtc_sdp.cc @@ -3542,6 +3542,11 @@ bool ParseSsrcGroupAttribute(absl::string_view line, if (!GetValueFromString(line, fields[i], &ssrc, error)) { return false; } + // Reject duplicates. While not forbidden by RFC 5576, + // they don't make sense. + if (absl::c_linear_search(ssrcs, ssrc)) { + return ParseFailed(line, "Duplicate SSRC in ssrc-group", error); + } ssrcs.push_back(ssrc); } ssrc_groups->push_back(SsrcGroup(semantics, ssrcs)); diff --git a/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc b/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc index 0e1e62e53f099..b2c751717e7bb 100644 --- a/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc +++ b/third_party/libwebrtc/pc/webrtc_sdp_unittest.cc @@ -5056,3 +5056,29 @@ TEST_F(WebRtcSdpTest, RejectSessionLevelMediaLevelExtmapMixedUsage) { JsepSessionDescription jdesc(kDummyType); EXPECT_FALSE(SdpDeserialize(sdp, &jdesc)); } + +TEST_F(WebRtcSdpTest, RejectDuplicateSsrcInSsrcGroup) { + std::string sdp = + "v=0\r\n" + "o=- 0 3 IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n" + "a=group:BUNDLE 0\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=ice-ufrag:ETEn\r\n" + "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n" + "m=video 9 UDP/TLS/RTP/SAVPF 96 97\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 VP8/90000\r\n" + "a=rtpmap:97 rtx/90000\r\n" + "a=fmtp:97 apt=96\r\n" + "a=ssrc-group:FID 1234 1234\r\n" + "a=ssrc:1234 cname:test\r\n"; + JsepSessionDescription jdesc(kDummyType); + EXPECT_FALSE(SdpDeserialize(sdp, &jdesc)); +} diff --git a/third_party/libwebrtc/rtc_base/async_packet_socket.cc b/third_party/libwebrtc/rtc_base/async_packet_socket.cc index 1ce0d3b122aae..465a35d9c2698 100644 --- a/third_party/libwebrtc/rtc_base/async_packet_socket.cc +++ b/third_party/libwebrtc/rtc_base/async_packet_socket.cc @@ -24,10 +24,6 @@ PacketOptions::PacketOptions(DiffServCodePoint dscp) : dscp(dscp) {} PacketOptions::PacketOptions(const PacketOptions& other) = default; PacketOptions::~PacketOptions() = default; -AsyncPacketSocket::AsyncPacketSocket() { - network_checker_.Detach(); -} - AsyncPacketSocket::~AsyncPacketSocket() = default; void AsyncPacketSocket::SubscribeClose( diff --git a/third_party/libwebrtc/rtc_base/async_packet_socket.h b/third_party/libwebrtc/rtc_base/async_packet_socket.h index aa31e25eab7b9..90f2a13945488 100644 --- a/third_party/libwebrtc/rtc_base/async_packet_socket.h +++ b/third_party/libwebrtc/rtc_base/async_packet_socket.h @@ -68,7 +68,7 @@ class RTC_EXPORT AsyncPacketSocket : public sigslot::has_slots<> { STATE_CONNECTED }; - AsyncPacketSocket(); + AsyncPacketSocket() = default; ~AsyncPacketSocket() override; AsyncPacketSocket(const AsyncPacketSocket&) = delete; @@ -148,7 +148,8 @@ class RTC_EXPORT AsyncPacketSocket : public sigslot::has_slots<> { on_close_.Send(this, err); } - RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_checker_; + RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker network_checker_{ + webrtc::SequenceChecker::kDetached}; private: webrtc::CallbackList on_close_ diff --git a/third_party/libwebrtc/rtc_base/async_resolver.cc b/third_party/libwebrtc/rtc_base/async_resolver.cc index 7c1a6fe78daa7..48c16136d24c0 100644 --- a/third_party/libwebrtc/rtc_base/async_resolver.cc +++ b/third_party/libwebrtc/rtc_base/async_resolver.cc @@ -152,29 +152,29 @@ void AsyncResolver::Start(const SocketAddress& addr, int family) { RTC_DCHECK_RUN_ON(&sequence_checker_); RTC_DCHECK(!destroy_called_); addr_ = addr; - auto thread_function = - [this, addr, family, caller_task_queue = webrtc::TaskQueueBase::Current(), - state = state_] { - std::vector addresses; - int error = ResolveHostname(addr.hostname(), family, &addresses); - webrtc::MutexLock lock(&state->mutex); - if (state->status == State::Status::kLive) { - caller_task_queue->PostTask( - [this, error, addresses = std::move(addresses), state] { - bool live; - { - // ResolveDone can lead to instance destruction, so make sure - // we don't deadlock. - webrtc::MutexLock lock(&state->mutex); - live = state->status == State::Status::kLive; - } - if (live) { - RTC_DCHECK_RUN_ON(&sequence_checker_); - ResolveDone(std::move(addresses), error); - } - }); - } - }; + auto thread_function = [this, addr, family, + caller_task_queue = webrtc::TaskQueueBase::Current(), + state = state_] { + std::vector addresses; + int error = ResolveHostname(addr.hostname(), family, &addresses); + webrtc::MutexLock lock(&state->mutex); + if (state->status == State::Status::kLive) { + caller_task_queue->PostTask( + [this, error, addresses = std::move(addresses), state] { + bool live; + { + // ResolveDone can lead to instance destruction, so make sure + // we don't deadlock. + webrtc::MutexLock lock(&state->mutex); + live = state->status == State::Status::kLive; + } + if (live) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + ResolveDone(std::move(addresses), error); + } + }); + } + }; #if defined(WEBRTC_MAC) || defined(WEBRTC_IOS) PostTaskToGlobalQueue( std::make_unique>(thread_function)); diff --git a/third_party/libwebrtc/rtc_base/async_tcp_socket.cc b/third_party/libwebrtc/rtc_base/async_tcp_socket.cc index d29eafddb9c77..97e8611fe2527 100644 --- a/third_party/libwebrtc/rtc_base/async_tcp_socket.cc +++ b/third_party/libwebrtc/rtc_base/async_tcp_socket.cc @@ -61,8 +61,7 @@ Socket* AsyncTCPSocketBase::ConnectSocket( return owned_socket.release(); } -AsyncTCPSocketBase::AsyncTCPSocketBase(Socket* socket, - size_t max_packet_size) +AsyncTCPSocketBase::AsyncTCPSocketBase(Socket* socket, size_t max_packet_size) : socket_(socket), max_insize_(max_packet_size), max_outsize_(max_packet_size) { diff --git a/third_party/libwebrtc/rtc_base/callback_list_unittest.cc b/third_party/libwebrtc/rtc_base/callback_list_unittest.cc index 483eb3f99a12a..86c2009fe3b2c 100644 --- a/third_party/libwebrtc/rtc_base/callback_list_unittest.cc +++ b/third_party/libwebrtc/rtc_base/callback_list_unittest.cc @@ -7,11 +7,12 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ +#include "rtc_base/callback_list.h" + #include #include #include "api/function_view.h" -#include "rtc_base/callback_list.h" #include "test/gtest.h" namespace webrtc { @@ -25,7 +26,7 @@ TEST(CallbackList, NoReceiverSingleMessageTest) { TEST(CallbackList, MultipleParameterMessageTest) { CallbackList + std::string&> c; std::string str = "messege"; int i = 10; diff --git a/third_party/libwebrtc/rtc_base/checks.h b/third_party/libwebrtc/rtc_base/checks.h index 459c6a5ebb5da..99fee97d0a48b 100644 --- a/third_party/libwebrtc/rtc_base/checks.h +++ b/third_party/libwebrtc/rtc_base/checks.h @@ -411,22 +411,20 @@ RTC_NORETURN RTC_EXPORT void UnreachableCodeReached(); ::rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2) #else #define RTC_CHECK(condition) \ - (condition) \ - ? static_cast(0) \ - : true ? ::rtc::webrtc_checks_impl::FatalLogCall(__FILE__, \ - __LINE__, "") & \ - ::rtc::webrtc_checks_impl::LogStreamer<>() \ - : ::rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ - ::rtc::webrtc_checks_impl::LogStreamer<>() + (condition) ? static_cast(0) \ + : true ? ::rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, \ + "") & \ + ::rtc::webrtc_checks_impl::LogStreamer<>() \ + : ::rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ + ::rtc::webrtc_checks_impl::LogStreamer<>() #define RTC_CHECK_OP(name, op, val1, val2) \ - ::rtc::Safe##name((val1), (val2)) \ - ? static_cast(0) \ - : true ? ::rtc::webrtc_checks_impl::FatalLogCall(__FILE__, \ - __LINE__, "") & \ - ::rtc::webrtc_checks_impl::LogStreamer<>() \ - : ::rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ - ::rtc::webrtc_checks_impl::LogStreamer<>() + ::rtc::Safe##name((val1), (val2)) ? static_cast(0) \ + : true ? ::rtc::webrtc_checks_impl::FatalLogCall(__FILE__, __LINE__, \ + "") & \ + ::rtc::webrtc_checks_impl::LogStreamer<>() \ + : ::rtc::webrtc_checks_impl::FatalLogCall("", 0, "") & \ + ::rtc::webrtc_checks_impl::LogStreamer<>() #endif #define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2) diff --git a/third_party/libwebrtc/rtc_base/event_tracer_unittest.cc b/third_party/libwebrtc/rtc_base/event_tracer_unittest.cc index f4d41e4e7c748..d0783c3f2df7b 100644 --- a/third_party/libwebrtc/rtc_base/event_tracer_unittest.cc +++ b/third_party/libwebrtc/rtc_base/event_tracer_unittest.cc @@ -61,17 +61,11 @@ TEST(EventTracerTest, ScopedTraceEvent) { [](const char* /*name*/) { return reinterpret_cast("test"); }, - [](char /*phase*/, - const unsigned char* /*category_enabled*/, - const char* /*name*/, - unsigned long long /*id*/, - int /*num_args*/, - const char** /*arg_names*/, - const unsigned char* /*arg_types*/, + [](char /*phase*/, const unsigned char* /*category_enabled*/, + const char* /*name*/, unsigned long long /*id*/, int /*num_args*/, + const char** /*arg_names*/, const unsigned char* /*arg_types*/, const unsigned long long* /*arg_values*/, - unsigned char /*flags*/) { - TestStatistics::Get()->Increment(); - }); + unsigned char /*flags*/) { TestStatistics::Get()->Increment(); }); { TRACE_EVENT0("test", "ScopedTraceEvent"); } EXPECT_EQ(2, TestStatistics::Get()->Count()); TestStatistics::Get()->Reset(); diff --git a/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings.h b/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings.h index 0b5e03df3b0c2..2bca73dfb9619 100644 --- a/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings.h +++ b/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings.h @@ -96,9 +96,9 @@ class BalancedDegradationSettings { int pixels = 0; // Video frame size. // If the frame size is less than or equal to `pixels`: - int fps = 0; // Min framerate to be used. - int kbps = 0; // Min bitrate needed to adapt up (resolution/fps). - int kbps_res = 0; // Min bitrate needed to adapt up in resolution. + int fps = 0; // Min framerate to be used. + int kbps = 0; // Min bitrate needed to adapt up (resolution/fps). + int kbps_res = 0; // Min bitrate needed to adapt up in resolution. int fps_diff = kNoFpsDiff; // Min fps reduction needed (input fps - `fps`) // w/o triggering a new subsequent downgrade // check. diff --git a/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings_unittest.cc b/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings_unittest.cc index a32dbb4aaa61f..996c06f8f238a 100644 --- a/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings_unittest.cc +++ b/third_party/libwebrtc/rtc_base/experiments/balanced_degradation_settings_unittest.cc @@ -21,40 +21,39 @@ namespace { void VerifyIsDefault( const std::vector& config) { - EXPECT_THAT(config, ::testing::ElementsAre( - BalancedDegradationSettings::Config{ - 320 * 240, - 7, - 0, - 0, - BalancedDegradationSettings::kNoFpsDiff, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}}, - BalancedDegradationSettings::Config{ - 480 * 360, - 10, - 0, - 0, - 1, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}}, - BalancedDegradationSettings::Config{ - 640 * 480, - 15, - 0, - 0, - 1, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}})); + EXPECT_THAT(config, + ::testing::ElementsAre( + BalancedDegradationSettings::Config{ + 320 * 240, + 7, + 0, + 0, + BalancedDegradationSettings::kNoFpsDiff, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}}, + BalancedDegradationSettings::Config{480 * 360, + 10, + 0, + 0, + 1, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}}, + BalancedDegradationSettings::Config{640 * 480, + 15, + 0, + 0, + 1, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}})); } } // namespace diff --git a/third_party/libwebrtc/rtc_base/experiments/cpu_speed_experiment.h b/third_party/libwebrtc/rtc_base/experiments/cpu_speed_experiment.h index 025c1ea8c9d4e..24ec0c0ec69ac 100644 --- a/third_party/libwebrtc/rtc_base/experiments/cpu_speed_experiment.h +++ b/third_party/libwebrtc/rtc_base/experiments/cpu_speed_experiment.h @@ -14,7 +14,6 @@ #include #include "absl/types/optional.h" - #include "rtc_base/experiments/field_trial_parser.h" namespace webrtc { diff --git a/third_party/libwebrtc/rtc_base/experiments/encoder_info_settings.cc b/third_party/libwebrtc/rtc_base/experiments/encoder_info_settings.cc index 2e90a215130ac..00974838ae301 100644 --- a/third_party/libwebrtc/rtc_base/experiments/encoder_info_settings.cc +++ b/third_party/libwebrtc/rtc_base/experiments/encoder_info_settings.cc @@ -47,10 +47,6 @@ EncoderInfoSettings::GetDefaultSinglecastBitrateLimits( {960 * 540, 350000, 30000, 1000000}, {1280 * 720, 480000, 30000, 1500000}}; } - // Don't override existing AV1 limits with default values. - if (codec_type == kVideoCodecAV1) { - return {}; - } return {{320 * 180, 0, 30000, 300000}, {480 * 270, 200000, 30000, 500000}, diff --git a/third_party/libwebrtc/rtc_base/experiments/field_trial_list.h b/third_party/libwebrtc/rtc_base/experiments/field_trial_list.h index 261977243a35c..63403cc51d5d5 100644 --- a/third_party/libwebrtc/rtc_base/experiments/field_trial_list.h +++ b/third_party/libwebrtc/rtc_base/experiments/field_trial_list.h @@ -123,7 +123,7 @@ template struct LambdaTypeTraits : public LambdaTypeTraits {}; template -struct LambdaTypeTraits { +struct LambdaTypeTraits { using ret = RetType; using src = SourceType; }; diff --git a/third_party/libwebrtc/rtc_base/experiments/struct_parameters_parser_unittest.cc b/third_party/libwebrtc/rtc_base/experiments/struct_parameters_parser_unittest.cc index 2f92b9fc6a925..0824bd3b2771a 100644 --- a/third_party/libwebrtc/rtc_base/experiments/struct_parameters_parser_unittest.cc +++ b/third_party/libwebrtc/rtc_base/experiments/struct_parameters_parser_unittest.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ #include "rtc_base/experiments/struct_parameters_parser.h" + #include "rtc_base/gunit.h" namespace webrtc { diff --git a/third_party/libwebrtc/rtc_base/fake_network.h b/third_party/libwebrtc/rtc_base/fake_network.h index d78d8a773051b..bc0330606f21e 100644 --- a/third_party/libwebrtc/rtc_base/fake_network.h +++ b/third_party/libwebrtc/rtc_base/fake_network.h @@ -110,7 +110,7 @@ class FakeNetworkManager : public NetworkManagerBase { IPAddress prefix = TruncateIP(it->socket_address.ipaddr(), prefix_length); auto net = std::make_unique( it->socket_address.hostname(), it->socket_address.hostname(), prefix, - prefix_length, it->adapter_type, /*field_trials=*/nullptr); + prefix_length, it->adapter_type); if (it->underlying_vpn_adapter_type.has_value()) { net->set_underlying_type_for_vpn(*it->underlying_vpn_adapter_type); } diff --git a/third_party/libwebrtc/rtc_base/ip_address.cc b/third_party/libwebrtc/rtc_base/ip_address.cc index d544b611e1499..9e436e3c78fbc 100644 --- a/third_party/libwebrtc/rtc_base/ip_address.cc +++ b/third_party/libwebrtc/rtc_base/ip_address.cc @@ -22,9 +22,8 @@ #include #endif -#include "rtc_base/ip_address.h" - #include "rtc_base/byte_order.h" +#include "rtc_base/ip_address.h" #include "rtc_base/net_helpers.h" #include "rtc_base/string_utils.h" diff --git a/third_party/libwebrtc/rtc_base/logging.cc b/third_party/libwebrtc/rtc_base/logging.cc index ef517f1df8629..eac04fdc0686a 100644 --- a/third_party/libwebrtc/rtc_base/logging.cc +++ b/third_party/libwebrtc/rtc_base/logging.cc @@ -375,9 +375,8 @@ void LogMessage::OutputToDebug(const LogLineRef& log_line) { CFStringRef domain = CFBundleGetIdentifier(CFBundleGetMainBundle()); if (domain != nullptr) { Boolean exists_and_is_valid; - Boolean should_log = - CFPreferencesGetAppBooleanValue(CFSTR("logToStdErr"), domain, - &exists_and_is_valid); + Boolean should_log = CFPreferencesGetAppBooleanValue( + CFSTR("logToStdErr"), domain, &exists_and_is_valid); // If the key doesn't exist or is invalid or is false, we will not log to // stderr. log_to_stderr = exists_and_is_valid && should_log; diff --git a/third_party/libwebrtc/rtc_base/network.cc b/third_party/libwebrtc/rtc_base/network.cc index bbcf690915dae..6279f7f0eafd9 100644 --- a/third_party/libwebrtc/rtc_base/network.cc +++ b/third_party/libwebrtc/rtc_base/network.cc @@ -154,16 +154,19 @@ bool IsIgnoredIPv6(bool allow_mac_based_ipv6, const InterfaceAddress& ip) { // However, our IPAddress structure doesn't carry that so the // information is lost and causes binding failure. if (IPIsLinkLocal(ip)) { + RTC_LOG(LS_INFO) << "Ignore link local IP:" << ip.ToSensitiveString(); return true; } // Any MAC based IPv6 should be avoided to prevent the MAC tracking. if (IPIsMacBased(ip) && !allow_mac_based_ipv6) { + RTC_LOG(LS_INFO) << "Ignore Mac based IP:" << ip.ToSensitiveString(); return true; } // Ignore deprecated IPv6. if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED) { + RTC_LOG(LS_INFO) << "Ignore deprecated IP:" << ip.ToSensitiveString(); return true; } @@ -183,20 +186,21 @@ bool ShouldAdapterChangeTriggerNetworkChange(rtc::AdapterType old_type, return true; } -bool PreferGlobalIPv6Address(const webrtc::FieldTrialsView* field_trials) { - // Bug fix to prefer global IPv6 address over link local. +#if defined(WEBRTC_WIN) +bool IpAddressAttributesEnabled(const webrtc::FieldTrialsView* field_trials) { // Field trial key reserved in bugs.webrtc.org/14334 if (field_trials && field_trials->IsEnabled("WebRTC-IPv6NetworkResolutionFixes")) { - webrtc::FieldTrialParameter prefer_global_ipv6_address_enabled( - "PreferGlobalIPv6Address", false); + webrtc::FieldTrialParameter ip_address_attributes_enabled( + "IpAddressAttributesEnabled", false); webrtc::ParseFieldTrial( - {&prefer_global_ipv6_address_enabled}, + {&ip_address_attributes_enabled}, field_trials->Lookup("WebRTC-IPv6NetworkResolutionFixes")); - return prefer_global_ipv6_address_enabled; + return ip_address_attributes_enabled; } return false; } +#endif // WEBRTC_WIN } // namespace @@ -325,7 +329,7 @@ std::unique_ptr NetworkManagerBase::CreateNetwork( int prefix_length, AdapterType type) const { return std::make_unique(name, description, prefix, prefix_length, - type, field_trials_.get()); + type); } std::vector NetworkManagerBase::GetAnyAddressNetworks() { @@ -545,6 +549,7 @@ BasicNetworkManager::BasicNetworkManager( SocketFactory* socket_factory, const webrtc::FieldTrialsView* field_trials_view) : NetworkManagerBase(field_trials_view), + field_trials_(field_trials_view), network_monitor_factory_(network_monitor_factory), socket_factory_(socket_factory), allow_mac_based_ipv6_( @@ -812,12 +817,27 @@ bool BasicNetworkManager::CreateNetworks( sockaddr_in6* v6_addr = reinterpret_cast(address->Address.lpSockaddr); scope_id = v6_addr->sin6_scope_id; - ip = IPAddress(v6_addr->sin6_addr); - if (IsIgnoredIPv6(allow_mac_based_ipv6_, InterfaceAddress(ip))) { + // From http://technet.microsoft.com/en-us/ff568768(v=vs.60).aspx, + // the way to identify a temporary IPv6 Address is to check if + // PrefixOrigin is equal to IpPrefixOriginRouterAdvertisement and + // SuffixOrigin equal to IpSuffixOriginRandom. + int ip_address_attributes = IPV6_ADDRESS_FLAG_NONE; + if (IpAddressAttributesEnabled(field_trials_.get())) { + if (address->PrefixOrigin == IpPrefixOriginRouterAdvertisement && + address->SuffixOrigin == IpSuffixOriginRandom) { + ip_address_attributes |= IPV6_ADDRESS_FLAG_TEMPORARY; + } + if (address->PreferredLifetime == 0) { + ip_address_attributes |= IPV6_ADDRESS_FLAG_DEPRECATED; + } + } + if (IsIgnoredIPv6(allow_mac_based_ipv6_, + InterfaceAddress(v6_addr->sin6_addr, + ip_address_attributes))) { continue; } - + ip = InterfaceAddress(v6_addr->sin6_addr, ip_address_attributes); break; } default: { @@ -1094,10 +1114,8 @@ Network::Network(absl::string_view name, absl::string_view desc, const IPAddress& prefix, int prefix_length, - AdapterType type, - const webrtc::FieldTrialsView* field_trials) - : field_trials_(field_trials), - name_(name), + AdapterType type) + : name_(name), description_(desc), prefix_(prefix), prefix_length_(prefix_length), @@ -1141,15 +1159,13 @@ IPAddress Network::GetBestIP() const { } InterfaceAddress selected_ip, link_local_ip, ula_ip; - const bool prefer_global_ipv6_to_link_local = - PreferGlobalIPv6Address(field_trials_); for (const InterfaceAddress& ip : ips_) { // Ignore any address which has been deprecated already. if (ip.ipv6_flags() & IPV6_ADDRESS_FLAG_DEPRECATED) continue; - if (prefer_global_ipv6_to_link_local && IPIsLinkLocal(ip)) { + if (IPIsLinkLocal(ip)) { link_local_ip = ip; continue; } @@ -1168,7 +1184,7 @@ IPAddress Network::GetBestIP() const { } if (IPIsUnspec(selected_ip)) { - if (prefer_global_ipv6_to_link_local && !IPIsUnspec(link_local_ip)) { + if (!IPIsUnspec(link_local_ip)) { // No proper global IPv6 address found, use link local address instead. selected_ip = link_local_ip; } else if (!IPIsUnspec(ula_ip)) { diff --git a/third_party/libwebrtc/rtc_base/network.h b/third_party/libwebrtc/rtc_base/network.h index c7d73bff7ad2e..4a97a45d4d0da 100644 --- a/third_party/libwebrtc/rtc_base/network.h +++ b/third_party/libwebrtc/rtc_base/network.h @@ -361,6 +361,9 @@ class RTC_EXPORT BasicNetworkManager : public NetworkManagerBase, bool sent_first_update_ = true; int start_count_ = 0; + webrtc::AlwaysValidPointer + field_trials_; std::vector network_ignore_list_; NetworkMonitorFactory* const network_monitor_factory_; SocketFactory* const socket_factory_; @@ -379,21 +382,18 @@ class RTC_EXPORT Network { Network(absl::string_view name, absl::string_view description, const IPAddress& prefix, - int prefix_length, - const webrtc::FieldTrialsView* field_trials = nullptr) + int prefix_length) : Network(name, description, prefix, prefix_length, - rtc::ADAPTER_TYPE_UNKNOWN, - field_trials) {} + rtc::ADAPTER_TYPE_UNKNOWN) {} Network(absl::string_view name, absl::string_view description, const IPAddress& prefix, int prefix_length, - AdapterType type, - const webrtc::FieldTrialsView* field_trials = nullptr); + AdapterType type); Network(const Network&); ~Network(); @@ -442,8 +442,7 @@ class RTC_EXPORT Network { // Here is the rule on how we mark the IPv6 address as ignorable for WebRTC. // 1) return all global temporary dynamic and non-deprecated ones. // 2) if #1 not available, return global ones. - // 3) if #2 not available and WebRTC-IPv6NetworkResolutionFixes enabled, - // return local link ones. + // 3) if #2 not available, return local link ones. // 4) if #3 not available, use ULA ipv6 as last resort. (ULA stands for // unique local address, which is not route-able in open internet but might // be useful for a close WebRTC deployment. @@ -577,7 +576,6 @@ class RTC_EXPORT Network { std::string ToString() const; private: - const webrtc::FieldTrialsView* field_trials_ = nullptr; const DefaultLocalAddressProvider* default_local_address_provider_ = nullptr; const MdnsResponderProvider* mdns_responder_provider_ = nullptr; std::string name_; diff --git a/third_party/libwebrtc/rtc_base/network_route.cc b/third_party/libwebrtc/rtc_base/network_route.cc index 80d135a92c1f4..9762dc2eb71c2 100644 --- a/third_party/libwebrtc/rtc_base/network_route.cc +++ b/third_party/libwebrtc/rtc_base/network_route.cc @@ -20,8 +20,8 @@ bool RouteEndpoint::operator==(const RouteEndpoint& other) const { bool NetworkRoute::operator==(const NetworkRoute& other) const { return connected == other.connected && local == other.local && - remote == other.remote && packet_overhead == other.packet_overhead && - last_sent_packet_id == other.last_sent_packet_id; + remote == other.remote && packet_overhead == other.packet_overhead && + last_sent_packet_id == other.last_sent_packet_id; } } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/network_unittest.cc b/third_party/libwebrtc/rtc_base/network_unittest.cc index 93ed6172d1abf..9f76d5b44223c 100644 --- a/third_party/libwebrtc/rtc_base/network_unittest.cc +++ b/third_party/libwebrtc/rtc_base/network_unittest.cc @@ -340,11 +340,9 @@ TEST_F(NetworkTest, TestNetworkConstruct) { TEST_F(NetworkTest, TestIsIgnoredNetworkIgnoresIPsStartingWith0) { Network ipv4_network1("test_eth0", "Test Network Adapter 1", - IPAddress(0x12345600U), 24, ADAPTER_TYPE_ETHERNET, - &field_trials_); + IPAddress(0x12345600U), 24, ADAPTER_TYPE_ETHERNET); Network ipv4_network2("test_eth1", "Test Network Adapter 2", - IPAddress(0x010000U), 24, ADAPTER_TYPE_ETHERNET, - &field_trials_); + IPAddress(0x010000U), 24, ADAPTER_TYPE_ETHERNET); PhysicalSocketServer socket_server; BasicNetworkManager network_manager(&socket_server); network_manager.StartUpdating(); @@ -824,19 +822,19 @@ TEST_F(NetworkTest, NetworksSortedByInterfaceName) { TEST_F(NetworkTest, TestNetworkAdapterTypes) { Network wifi("wlan0", "Wireless Adapter", IPAddress(0x12345600U), 24, - ADAPTER_TYPE_WIFI, &field_trials_); + ADAPTER_TYPE_WIFI); EXPECT_EQ(ADAPTER_TYPE_WIFI, wifi.type()); Network ethernet("eth0", "Ethernet", IPAddress(0x12345600U), 24, - ADAPTER_TYPE_ETHERNET, &field_trials_); + ADAPTER_TYPE_ETHERNET); EXPECT_EQ(ADAPTER_TYPE_ETHERNET, ethernet.type()); Network cellular("test_cell", "Cellular Adapter", IPAddress(0x12345600U), 24, - ADAPTER_TYPE_CELLULAR, &field_trials_); + ADAPTER_TYPE_CELLULAR); EXPECT_EQ(ADAPTER_TYPE_CELLULAR, cellular.type()); Network vpn("bridge_test", "VPN Adapter", IPAddress(0x12345600U), 24, - ADAPTER_TYPE_VPN, &field_trials_); + ADAPTER_TYPE_VPN); EXPECT_EQ(ADAPTER_TYPE_VPN, vpn.type()); Network unknown("test", "Test Adapter", IPAddress(0x12345600U), 24, - ADAPTER_TYPE_UNKNOWN, &field_trials_); + ADAPTER_TYPE_UNKNOWN); EXPECT_EQ(ADAPTER_TYPE_UNKNOWN, unknown.type()); } @@ -1159,9 +1157,6 @@ TEST_F(NetworkTest, TestIPv6Selection) { // Test that the filtering logic follows the defined ruleset in network.h. TEST_F(NetworkTest, TestGetBestIPWithPreferGlobalIPv6ToLinkLocalEnabled) { - webrtc::test::ScopedKeyValueConfig field_trials( - "WebRTC-IPv6NetworkResolutionFixes/" - "Enabled,PreferGlobalIPv6Address:true/"); InterfaceAddress ip, link_local; std::string ipstr; @@ -1170,7 +1165,7 @@ TEST_F(NetworkTest, TestGetBestIPWithPreferGlobalIPv6ToLinkLocalEnabled) { // Create a network with this prefix. Network ipv6_network("test_eth0", "Test NetworkAdapter", TruncateIP(ip, 64), - 64, ADAPTER_TYPE_UNKNOWN, &field_trials); + 64, ADAPTER_TYPE_UNKNOWN); // When there is no address added, it should return an unspecified // address. diff --git a/third_party/libwebrtc/rtc_base/numerics/event_based_exponential_moving_average.h b/third_party/libwebrtc/rtc_base/numerics/event_based_exponential_moving_average.h index a59fff72417a2..69f4e614cbca0 100644 --- a/third_party/libwebrtc/rtc_base/numerics/event_based_exponential_moving_average.h +++ b/third_party/libwebrtc/rtc_base/numerics/event_based_exponential_moving_average.h @@ -14,6 +14,7 @@ #include #include #include + #include "absl/types/optional.h" namespace rtc { diff --git a/third_party/libwebrtc/rtc_base/numerics/safe_minmax.h b/third_party/libwebrtc/rtc_base/numerics/safe_minmax.h index 6c41dfd617f0c..8356536dbc7eb 100644 --- a/third_party/libwebrtc/rtc_base/numerics/safe_minmax.h +++ b/third_party/libwebrtc/rtc_base/numerics/safe_minmax.h @@ -325,9 +325,9 @@ R2 SafeClamp(T x, L min, H max) { static_assert(IsIntlike::value || std::is_floating_point::value, "The third argument must be integral or floating-point"); RTC_DCHECK_LE(min, max); - return SafeLe(x, min) - ? static_cast(min) - : SafeGe(x, max) ? static_cast(max) : static_cast(x); + return SafeLe(x, min) ? static_cast(min) + : SafeGe(x, max) ? static_cast(max) + : static_cast(x); } } // namespace rtc diff --git a/third_party/libwebrtc/rtc_base/openssl_utility_unittest.cc b/third_party/libwebrtc/rtc_base/openssl_utility_unittest.cc index d090524cde3d1..3302490bd069f 100644 --- a/third_party/libwebrtc/rtc_base/openssl_utility_unittest.cc +++ b/third_party/libwebrtc/rtc_base/openssl_utility_unittest.cc @@ -184,7 +184,6 @@ enum ssl_verify_result_t DummyVerifyCallback(SSL* ssl, uint8_t* out_alert) { // The server is deallocated. This client will have a peer certificate available // and is thus suitable for testing VerifyPeerCertMatchesHost. SSL* CreateSSLWithPeerCertificate(const unsigned char* cert, size_t cert_len) { - const unsigned char* key_ptr = kFakeSSLPrivateKey; EVP_PKEY* key = d2i_PrivateKey( EVP_PKEY_EC, nullptr, &key_ptr, diff --git a/third_party/libwebrtc/rtc_base/proxy_server.cc b/third_party/libwebrtc/rtc_base/proxy_server.cc index 652e4c5ce8a2e..84c96213c3298 100644 --- a/third_party/libwebrtc/rtc_base/proxy_server.cc +++ b/third_party/libwebrtc/rtc_base/proxy_server.cc @@ -13,6 +13,7 @@ #include #include + #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/socket_factory.h" diff --git a/third_party/libwebrtc/rtc_base/rate_statistics.h b/third_party/libwebrtc/rtc_base/rate_statistics.h index dc8d7f5272a32..e7ce8ad5edc08 100644 --- a/third_party/libwebrtc/rtc_base/rate_statistics.h +++ b/third_party/libwebrtc/rtc_base/rate_statistics.h @@ -73,7 +73,7 @@ class RTC_EXPORT RateStatistics { struct Bucket { explicit Bucket(int64_t timestamp); - int64_t sum; // Sum of all samples in this bucket. + int64_t sum; // Sum of all samples in this bucket. int num_samples; // Number of samples in this bucket. const int64_t timestamp; // Timestamp this bucket corresponds to. }; diff --git a/third_party/libwebrtc/rtc_base/strings/string_format.cc b/third_party/libwebrtc/rtc_base/strings/string_format.cc index f92be339ce4aa..e69fb6193d700 100644 --- a/third_party/libwebrtc/rtc_base/strings/string_format.cc +++ b/third_party/libwebrtc/rtc_base/strings/string_format.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include - #include "rtc_base/strings/string_format.h" +#include + #include "rtc_base/checks.h" namespace rtc { diff --git a/third_party/libwebrtc/rtc_base/strong_alias_unittest.cc b/third_party/libwebrtc/rtc_base/strong_alias_unittest.cc index a87bc4de3738b..711c805e89c8c 100644 --- a/third_party/libwebrtc/rtc_base/strong_alias_unittest.cc +++ b/third_party/libwebrtc/rtc_base/strong_alias_unittest.cc @@ -62,8 +62,8 @@ TYPED_TEST(StrongAliasTest, ValueAccessesUnderlyingValue) { // Const value getter. const FooAlias const_alias(GetExampleValue(1)); EXPECT_EQ(GetExampleValue(1), const_alias.value()); - static_assert(std::is_const::type>::value, + static_assert(std::is_const::type>::value, "Reference returned by const value getter should be const."); } diff --git a/third_party/libwebrtc/rtc_base/synchronization/mutex.h b/third_party/libwebrtc/rtc_base/synchronization/mutex.h index 2cf0e67c3df42..104f4fd3e1f53 100644 --- a/third_party/libwebrtc/rtc_base/synchronization/mutex.h +++ b/third_party/libwebrtc/rtc_base/synchronization/mutex.h @@ -38,9 +38,7 @@ class RTC_LOCKABLE Mutex final { Mutex(const Mutex&) = delete; Mutex& operator=(const Mutex&) = delete; - void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { - impl_.Lock(); - } + void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION() { impl_.Lock(); } ABSL_MUST_USE_RESULT bool TryLock() RTC_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return impl_.TryLock(); } @@ -48,9 +46,7 @@ class RTC_LOCKABLE Mutex final { // Otherwise, may report an error (typically by crashing with a diagnostic), // or may return immediately. void AssertHeld() const RTC_ASSERT_EXCLUSIVE_LOCK() { impl_.AssertHeld(); } - void Unlock() RTC_UNLOCK_FUNCTION() { - impl_.Unlock(); - } + void Unlock() RTC_UNLOCK_FUNCTION() { impl_.Unlock(); } private: MutexImpl impl_; diff --git a/third_party/libwebrtc/rtc_base/thread_unittest.cc b/third_party/libwebrtc/rtc_base/thread_unittest.cc index d5b467c1f2a21..cd733db2cd5f2 100644 --- a/third_party/libwebrtc/rtc_base/thread_unittest.cc +++ b/third_party/libwebrtc/rtc_base/thread_unittest.cc @@ -738,11 +738,10 @@ TEST(ThreadPostTaskTest, InvokesAsynchronously) { // thread. The second event ensures that the message is processed. Event event_set_by_test_thread; Event event_set_by_background_thread; - background_thread->PostTask( - [&event_set_by_test_thread, &event_set_by_background_thread] { - WaitAndSetEvent(&event_set_by_test_thread, - &event_set_by_background_thread); - }); + background_thread->PostTask([&event_set_by_test_thread, + &event_set_by_background_thread] { + WaitAndSetEvent(&event_set_by_test_thread, &event_set_by_background_thread); + }); event_set_by_test_thread.Set(); event_set_by_background_thread.Wait(Event::kForever); } diff --git a/third_party/libwebrtc/rtc_base/unique_id_generator.h b/third_party/libwebrtc/rtc_base/unique_id_generator.h index d103caf2fcc2b..10dd4d3151eb2 100644 --- a/third_party/libwebrtc/rtc_base/unique_id_generator.h +++ b/third_party/libwebrtc/rtc_base/unique_id_generator.h @@ -53,7 +53,8 @@ class UniqueNumberGenerator { bool AddKnownId(TIntegral value); private: - RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_; + RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_{ + webrtc::SequenceChecker::kDetached}; static_assert(std::is_integral::value, "Must be integral type."); TIntegral counter_ RTC_GUARDED_BY(sequence_checker_); std::set known_ids_ RTC_GUARDED_BY(sequence_checker_); @@ -117,16 +118,12 @@ class UniqueStringGenerator { }; template -UniqueNumberGenerator::UniqueNumberGenerator() : counter_(0) { - sequence_checker_.Detach(); -} +UniqueNumberGenerator::UniqueNumberGenerator() : counter_(0) {} template UniqueNumberGenerator::UniqueNumberGenerator( ArrayView known_ids) - : counter_(0), known_ids_(known_ids.begin(), known_ids.end()) { - sequence_checker_.Detach(); -} + : counter_(0), known_ids_(known_ids.begin(), known_ids.end()) {} template UniqueNumberGenerator::~UniqueNumberGenerator() {} diff --git a/third_party/libwebrtc/rtc_base/units/unit_base.h b/third_party/libwebrtc/rtc_base/units/unit_base.h index e8f8ec1956fca..a6bdbf547dc40 100644 --- a/third_party/libwebrtc/rtc_base/units/unit_base.h +++ b/third_party/libwebrtc/rtc_base/units/unit_base.h @@ -141,10 +141,9 @@ class UnitBase { template constexpr typename std::enable_if::value, T>::type ToValue() const { - return IsPlusInfinity() - ? std::numeric_limits::infinity() - : IsMinusInfinity() ? -std::numeric_limits::infinity() - : value_; + return IsPlusInfinity() ? std::numeric_limits::infinity() + : IsMinusInfinity() ? -std::numeric_limits::infinity() + : value_; } template constexpr T ToValueOr(T fallback_value) const { diff --git a/third_party/libwebrtc/rtc_base/weak_ptr.cc b/third_party/libwebrtc/rtc_base/weak_ptr.cc index 09807e1705359..3bfa71b0b45a0 100644 --- a/third_party/libwebrtc/rtc_base/weak_ptr.cc +++ b/third_party/libwebrtc/rtc_base/weak_ptr.cc @@ -16,12 +16,7 @@ namespace rtc { namespace internal { -WeakReference::Flag::Flag() : is_valid_(true) { - // Flags only become bound when checked for validity, or invalidated, - // so that we can check that later validity/invalidation operations on - // the same Flag take place on the same sequence. - checker_.Detach(); -} +WeakReference::Flag::Flag() : is_valid_(true) {} void WeakReference::Flag::Invalidate() { RTC_DCHECK(checker_.IsCurrent()) diff --git a/third_party/libwebrtc/rtc_base/weak_ptr.h b/third_party/libwebrtc/rtc_base/weak_ptr.h index a9e6b3a990510..7e75b5b9be082 100644 --- a/third_party/libwebrtc/rtc_base/weak_ptr.h +++ b/third_party/libwebrtc/rtc_base/weak_ptr.h @@ -104,7 +104,8 @@ class WeakReference { ~Flag() override; - RTC_NO_UNIQUE_ADDRESS ::webrtc::SequenceChecker checker_; + RTC_NO_UNIQUE_ADDRESS ::webrtc::SequenceChecker checker_{ + webrtc::SequenceChecker::kDetached}; bool is_valid_; }; diff --git a/third_party/libwebrtc/rtc_base/win/create_direct3d_device.cc b/third_party/libwebrtc/rtc_base/win/create_direct3d_device.cc index 02fe340d562d8..35bbec1156686 100644 --- a/third_party/libwebrtc/rtc_base/win/create_direct3d_device.cc +++ b/third_party/libwebrtc/rtc_base/win/create_direct3d_device.cc @@ -11,6 +11,7 @@ #include "rtc_base/win/create_direct3d_device.h" #include + #include namespace { diff --git a/third_party/libwebrtc/rtc_base/win32_window.cc b/third_party/libwebrtc/rtc_base/win32_window.cc index 775535a759e0c..275237f4a65c1 100644 --- a/third_party/libwebrtc/rtc_base/win32_window.cc +++ b/third_party/libwebrtc/rtc_base/win32_window.cc @@ -25,10 +25,18 @@ ATOM Win32Window::window_class_ = 0; Win32Window::Win32Window() : wnd_(nullptr) {} -Win32Window::~Win32Window() { RTC_DCHECK(nullptr == wnd_); } +Win32Window::~Win32Window() { + RTC_DCHECK(nullptr == wnd_); +} -bool Win32Window::Create(HWND parent, const wchar_t* title, DWORD style, - DWORD exstyle, int x, int y, int cx, int cy) { +bool Win32Window::Create(HWND parent, + const wchar_t* title, + DWORD style, + DWORD exstyle, + int x, + int y, + int cx, + int cy) { if (wnd_) { // Window already exists. return false; @@ -83,7 +91,9 @@ void Win32Window::Shutdown() { } } -bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, +bool Win32Window::OnMessage(UINT uMsg, + WPARAM wParam, + LPARAM lParam, LRESULT& result) { switch (uMsg) { case WM_CLOSE: @@ -96,13 +106,17 @@ bool Win32Window::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, return false; } -bool Win32Window::OnClose() { return true; } +bool Win32Window::OnClose() { + return true; +} void Win32Window::OnNcDestroy() { // Do nothing. } } -LRESULT Win32Window::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, +LRESULT Win32Window::WndProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, LPARAM lParam) { Win32Window* that = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); diff --git a/third_party/libwebrtc/rtc_tools/BUILD.gn b/third_party/libwebrtc/rtc_tools/BUILD.gn index 9b1f1fecda242..1e5fb058113e9 100644 --- a/third_party/libwebrtc/rtc_tools/BUILD.gn +++ b/third_party/libwebrtc/rtc_tools/BUILD.gn @@ -190,6 +190,16 @@ if (!is_component_build) { ] deps = [ + "..//api/video_codecs:video_decoder_factory_template", + "..//api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "..//api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "..//api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "..//api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "..//api/video_codecs:video_encoder_factory_template", + "..//api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "..//api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "..//api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "..//api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../api:create_frame_generator", "../api:rtp_parameters", "../api:transport_api", @@ -197,8 +207,6 @@ if (!is_component_build) { "../api/task_queue:default_task_queue_factory", "../api/task_queue:task_queue", "../api/video:builtin_video_bitrate_allocator_factory", - "../api/video_codecs:builtin_video_decoder_factory", - "../api/video_codecs:builtin_video_encoder_factory", "../api/video_codecs:video_codecs_api", "../call", "../call:call_interfaces", @@ -215,8 +223,8 @@ if (!is_component_build) { "../rtc_base:threading", "../rtc_base/system:file_wrapper", "../test:fileutils", + "../test:frame_generator_capturer", "../test:rtp_test_utils", - "../test:video_test_common", "../video/config:encoder_config", "../video/config:streams_config", "//third_party/abseil-cpp/absl/flags:flag", @@ -274,10 +282,11 @@ if (!is_component_build) { "../test:run_loop", "../test:run_test", "../test:run_test_interface", - "../test:test_common", "../test:test_renderer", "../test:test_support", + "../test:test_video_capturer", "../test:video_test_common", + "../test:video_test_constants", "../test:video_test_support", "../test/time_controller:time_controller", "//third_party/abseil-cpp/absl/flags:flag", diff --git a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/BUILD.gn b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/BUILD.gn index 040061b3e8512..abe1b4a0e34c7 100644 --- a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/BUILD.gn +++ b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/BUILD.gn @@ -48,8 +48,16 @@ rtc_executable("data_channel_benchmark") { "../../api:scoped_refptr", "../../api/audio_codecs:builtin_audio_decoder_factory", "../../api/audio_codecs:builtin_audio_encoder_factory", - "../../api/video_codecs:builtin_video_decoder_factory", - "../../api/video_codecs:builtin_video_encoder_factory", + "../../api/video_codecs:video_decoder_factory_template", + "../../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../../api/video_codecs:video_encoder_factory_template", + "../../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../../rtc_base:logging", "../../rtc_base:refcount", "../../rtc_base:rtc_event", diff --git a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/data_channel_benchmark.cc b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/data_channel_benchmark.cc index 33776f37aae08..fa0b6ca9c4f6d 100644 --- a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/data_channel_benchmark.cc +++ b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/data_channel_benchmark.cc @@ -71,15 +71,16 @@ struct SetupMessage { } }; -class DataChannelObserverImpl : public webrtc::DataChannelObserver { +class DataChannelServerObserverImpl : public webrtc::DataChannelObserver { public: - explicit DataChannelObserverImpl(webrtc::DataChannelInterface* dc) - : dc_(dc), bytes_received_(0) {} + explicit DataChannelServerObserverImpl(webrtc::DataChannelInterface* dc, + rtc::Thread* signaling_thread) + : dc_(dc), signaling_thread_(signaling_thread) {} + void OnStateChange() override { - RTC_LOG(LS_INFO) << "State changed to " << dc_->state(); + RTC_LOG(LS_INFO) << "Server state changed to " << dc_->state(); switch (dc_->state()) { case webrtc::DataChannelInterface::DataState::kOpen: - open_event_.Set(); break; case webrtc::DataChannelInterface::DataState::kClosed: closed_event_.Set(); @@ -88,67 +89,136 @@ class DataChannelObserverImpl : public webrtc::DataChannelObserver { break; } } - void OnMessage(const webrtc::DataBuffer& buffer) override { - bytes_received_ += buffer.data.size(); - if (bytes_received_threshold_ && - bytes_received_ >= bytes_received_threshold_) { - bytes_received_event_.Set(); - } - if (setup_message_.empty() && !buffer.binary) { - setup_message_.assign(buffer.data.cdata(), buffer.data.size()); + void OnMessage(const webrtc::DataBuffer& buffer) override { + if (!buffer.binary) { + std::string setup_message(buffer.data.cdata(), buffer.data.size()); + setup_ = SetupMessage::FromString(setup_message); + remaining_data_ = setup_.transfer_size; setup_message_event_.Set(); } } + void OnBufferedAmountChange(uint64_t sent_data_size) override { - if (dc_->buffered_amount() < - webrtc::DataChannelInterface::MaxSendQueueSize() / 2) - low_buffered_threshold_event_.Set(); - else - low_buffered_threshold_event_.Reset(); + remaining_data_ -= sent_data_size; + // Allow the transport buffer to be drained before starting again. + if (buffer_ && dc_->buffered_amount() <= ok_to_resume_sending_threshold_) { + total_queued_up_ += buffer_->size(); + dc_->SendAsync(*buffer_, [this, buffer = buffer_](webrtc::RTCError err) { + OnSendAsyncComplete(err, buffer); + }); + buffer_ = nullptr; + } } - bool WaitForOpenState() { - return dc_->state() == webrtc::DataChannelInterface::DataState::kOpen || - open_event_.Wait(rtc::Event::kForever); + bool IsOkToCallOnTheNetworkThread() override { return true; } + + bool WaitForClosedState() { return closed_event_.Wait(rtc::Event::kForever); } + + bool WaitForSetupMessage() { + return setup_message_event_.Wait(rtc::Event::kForever); } - bool WaitForClosedState() { - return dc_->state() == webrtc::DataChannelInterface::DataState::kClosed || - closed_event_.Wait(rtc::Event::kForever); + + void StartSending() { + RTC_CHECK(remaining_data_) << "Error: no data to send"; + std::string data(std::min(setup_.packet_size, remaining_data_), '0'); + webrtc::DataBuffer* data_buffer = + new webrtc::DataBuffer(rtc::CopyOnWriteBuffer(data), true); + total_queued_up_ = data_buffer->size(); + dc_->SendAsync(*data_buffer, + [this, data_buffer = data_buffer](webrtc::RTCError err) { + OnSendAsyncComplete(err, data_buffer); + }); } - // Set how many received bytes are required until - // WaitForBytesReceivedThreshold return true. - void SetBytesReceivedThreshold(uint64_t bytes_received_threshold) { - bytes_received_threshold_ = bytes_received_threshold; - if (bytes_received_ >= bytes_received_threshold_) - bytes_received_event_.Set(); + const struct SetupMessage& parameters() const { return setup_; } + + private: + void OnSendAsyncComplete(webrtc::RTCError error, webrtc::DataBuffer* buffer) { + total_queued_up_ -= buffer->size(); + if (!error.ok()) { + RTC_CHECK_EQ(error.type(), webrtc::RTCErrorType::RESOURCE_EXHAUSTED); + RTC_CHECK(!buffer_); + // Buffer saturated. Retry when OnBufferedAmountChange() detects we can. + buffer_ = buffer; + return; + } + signaling_thread_->PostTask([this, buffer = buffer, + remaining_data = remaining_data_]() { + fprintf(stderr, "Progress: %zu / %zu (%zu%%)\n", + (setup_.transfer_size - remaining_data), setup_.transfer_size, + (100 - remaining_data * 100 / setup_.transfer_size)); + + if (!remaining_data) { + RTC_CHECK(!total_queued_up_); + // We're done. + delete buffer; + return; + } + + if (remaining_data < buffer->data.size()) { + buffer->data.SetSize(remaining_data); + } + + total_queued_up_ += buffer->size(); + dc_->SendAsync(*buffer, [this, buffer = buffer](webrtc::RTCError err) { + OnSendAsyncComplete(err, buffer); + }); + }); } - // Wait until the received byte count reaches the desired value. - bool WaitForBytesReceivedThreshold() { - return (bytes_received_threshold_ && - bytes_received_ >= bytes_received_threshold_) || - bytes_received_event_.Wait(rtc::Event::kForever); + + webrtc::DataChannelInterface* const dc_; + rtc::Thread* const signaling_thread_; + rtc::Event closed_event_; + rtc::Event setup_message_event_; + size_t remaining_data_ = 0u; + size_t total_queued_up_ = 0u; + struct SetupMessage setup_; + webrtc::DataBuffer* buffer_ = nullptr; + const uint64_t ok_to_resume_sending_threshold_ = + webrtc::DataChannelInterface::MaxSendQueueSize() / 2; +}; + +class DataChannelClientObserverImpl : public webrtc::DataChannelObserver { + public: + explicit DataChannelClientObserverImpl(webrtc::DataChannelInterface* dc, + uint64_t bytes_received_threshold) + : dc_(dc), bytes_received_threshold_(bytes_received_threshold) {} + + void OnStateChange() override { + RTC_LOG(LS_INFO) << "Client state changed to " << dc_->state(); + switch (dc_->state()) { + case webrtc::DataChannelInterface::DataState::kOpen: + open_event_.Set(); + break; + default: + break; + } } - bool WaitForLowbufferedThreshold() { - return low_buffered_threshold_event_.Wait(rtc::Event::kForever); + void OnMessage(const webrtc::DataBuffer& buffer) override { + bytes_received_ += buffer.data.size(); + if (bytes_received_ >= bytes_received_threshold_) { + bytes_received_event_.Set(); + } } - std::string SetupMessage() { return setup_message_; } - bool WaitForSetupMessage() { - return setup_message_event_.Wait(rtc::Event::kForever); + + void OnBufferedAmountChange(uint64_t sent_data_size) override {} + bool IsOkToCallOnTheNetworkThread() override { return true; } + + bool WaitForOpenState() { return open_event_.Wait(rtc::Event::kForever); } + + // Wait until the received byte count reaches the desired value. + bool WaitForBytesReceivedThreshold() { + return bytes_received_event_.Wait(rtc::Event::kForever); } private: - webrtc::DataChannelInterface* dc_; + webrtc::DataChannelInterface* const dc_; rtc::Event open_event_; - rtc::Event closed_event_; rtc::Event bytes_received_event_; - absl::optional bytes_received_threshold_; - uint64_t bytes_received_; - rtc::Event low_buffered_threshold_event_; - std::string setup_message_; - rtc::Event setup_message_event_; + const uint64_t bytes_received_threshold_; + uint64_t bytes_received_ = 0u; }; int RunServer() { @@ -163,7 +233,9 @@ int RunServer() { auto grpc_server = webrtc::GrpcSignalingServerInterface::Create( [factory = rtc::scoped_refptr( - factory)](webrtc::SignalingInterface* signaling) { + factory), + signaling_thread = + signaling_thread.get()](webrtc::SignalingInterface* signaling) { webrtc::PeerConnectionClient client(factory.get(), signaling); client.StartPeerConnection(); auto peer_connection = client.peerConnection(); @@ -171,9 +243,11 @@ int RunServer() { // Set up the data channel auto dc_or_error = peer_connection->CreateDataChannelOrError("benchmark", nullptr); + RTC_CHECK(dc_or_error.ok()); auto data_channel = dc_or_error.MoveValue(); auto data_channel_observer = - std::make_unique(data_channel.get()); + std::make_unique( + data_channel.get(), signaling_thread); data_channel->RegisterObserver(data_channel_observer.get()); absl::Cleanup unregister_observer( [data_channel] { data_channel->UnregisterObserver(); }); @@ -183,36 +257,14 @@ int RunServer() { // should be. // First message is "packet_size,transfer_size". data_channel_observer->WaitForSetupMessage(); - auto parameters = - SetupMessage::FromString(data_channel_observer->SetupMessage()); // Wait for the sender and receiver peers to stabilize (send all ACKs) // This makes it easier to isolate the sending part when profiling. absl::SleepFor(absl::Seconds(1)); - std::string data(parameters.packet_size, '0'); - size_t remaining_data = parameters.transfer_size; - auto begin_time = webrtc::Clock::GetRealTimeClock()->CurrentTime(); - while (remaining_data) { - if (remaining_data < data.size()) - data.resize(remaining_data); - - rtc::CopyOnWriteBuffer buffer(data); - webrtc::DataBuffer data_buffer(buffer, true); - if (!data_channel->Send(data_buffer)) { - // If the send() call failed, the buffers are full. - // We wait until there's more room. - data_channel_observer->WaitForLowbufferedThreshold(); - continue; - } - remaining_data -= buffer.size(); - fprintf(stderr, "Progress: %zu / %zu (%zu%%)\n", - (parameters.transfer_size - remaining_data), - parameters.transfer_size, - (100 - remaining_data * 100 / parameters.transfer_size)); - } + data_channel_observer->StartSending(); // Receiver signals the data channel close event when it has received // all the data it requested. @@ -220,8 +272,10 @@ int RunServer() { auto end_time = webrtc::Clock::GetRealTimeClock()->CurrentTime(); auto duration_ms = (end_time - begin_time).ms(); - double throughput = (parameters.transfer_size / 1024. / 1024.) / - (duration_ms / 1000.); + double throughput = + (data_channel_observer->parameters().transfer_size / 1024. / + 1024.) / + (duration_ms / 1000.); printf("Elapsed time: %zums %gMiB/s\n", duration_ms, throughput); }, port, oneshot); @@ -231,7 +285,7 @@ int RunServer() { grpc_server->Wait(); } - signaling_thread->Quit(); + signaling_thread->Stop(); return 0; } @@ -251,13 +305,18 @@ int RunClient() { webrtc::PeerConnectionClient client(factory.get(), grpc_client->signaling_client()); + std::unique_ptr observer; + // Set up the callback to receive the data channel from the sender. rtc::scoped_refptr data_channel; rtc::Event got_data_channel; client.SetOnDataChannel( - [&data_channel, &got_data_channel]( - rtc::scoped_refptr channel) { - data_channel = channel; + [&](rtc::scoped_refptr channel) { + data_channel = std::move(channel); + // DataChannel needs an observer to drain the read queue. + observer = std::make_unique( + data_channel.get(), transfer_size); + data_channel->RegisterObserver(observer.get()); got_data_channel.Set(); }); @@ -270,16 +329,12 @@ int RunClient() { // Wait for the data channel to be received got_data_channel.Wait(rtc::Event::kForever); - // DataChannel needs an observer to start draining the read queue - DataChannelObserverImpl observer(data_channel.get()); - observer.SetBytesReceivedThreshold(transfer_size); - data_channel->RegisterObserver(&observer); absl::Cleanup unregister_observer( [data_channel] { data_channel->UnregisterObserver(); }); // Send a configuration string to the server to tell it to send // 'packet_size' bytes packets and send a total of 'transfer_size' MB. - observer.WaitForOpenState(); + observer->WaitForOpenState(); SetupMessage setup_message = { .packet_size = packet_size, .transfer_size = transfer_size, @@ -290,14 +345,14 @@ int RunClient() { } // Wait until we have received all the data - observer.WaitForBytesReceivedThreshold(); + observer->WaitForBytesReceivedThreshold(); // Close the data channel, signaling to the server we have received // all the requested data. data_channel->Close(); } - signaling_thread->Quit(); + signaling_thread->Stop(); return 0; } diff --git a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc index cd02e7118add3..a6f8bf558c1bf 100644 --- a/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc +++ b/third_party/libwebrtc/rtc_tools/data_channel_benchmark/peer_connection_client.cc @@ -21,8 +21,16 @@ #include "api/rtc_error.h" #include "api/scoped_refptr.h" #include "api/set_remote_description_observer_interface.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "rtc_base/logging.h" #include "rtc_base/thread.h" @@ -137,8 +145,12 @@ PeerConnectionClient::CreateDefaultFactory(rtc::Thread* signaling_thread) { /*signaling_thread*/ signaling_thread, /*default_adm=*/nullptr, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), + std::make_unique>(), + std::make_unique>(), /*audio_mixer=*/nullptr, /*audio_processing=*/nullptr); if (!factory) { diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc index e2b4ecfe8d0cd..29dc26c22f9dd 100644 --- a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyze_audio.cc @@ -18,6 +18,7 @@ #include "modules/audio_coding/neteq/tools/audio_sink.h" #include "modules/audio_coding/neteq/tools/fake_decode_from_file.h" #include "modules/audio_coding/neteq/tools/neteq_delay_analyzer.h" +#include "modules/audio_coding/neteq/tools/neteq_event_log_input.h" #include "modules/audio_coding/neteq/tools/neteq_replacement_input.h" #include "modules/audio_coding/neteq/tools/neteq_test.h" #include "modules/audio_coding/neteq/tools/resample_input_audio_file.h" @@ -176,114 +177,6 @@ void CreateAudioEncoderNumChannelsGraph(const ParsedRtcEventLog& parsed_log, plot->SetTitle("Reported audio encoder number of channels"); } -class NetEqStreamInput : public test::NetEqInput { - public: - // Does not take any ownership, and all pointers must refer to valid objects - // that outlive the one constructed. - NetEqStreamInput(const std::vector* packet_stream, - const std::vector* output_events, - const std::vector* - neteq_set_minimum_delay_events, - absl::optional end_time_ms) - : packet_stream_(*packet_stream), - packet_stream_it_(packet_stream_.begin()), - output_events_it_(output_events->begin()), - output_events_end_(output_events->end()), - neteq_set_minimum_delay_events_it_( - neteq_set_minimum_delay_events->begin()), - neteq_set_minimum_delay_events_end_( - neteq_set_minimum_delay_events->end()), - end_time_ms_(end_time_ms) { - RTC_DCHECK(packet_stream); - RTC_DCHECK(output_events); - } - - absl::optional NextPacketTime() const override { - if (packet_stream_it_ == packet_stream_.end()) { - return absl::nullopt; - } - if (end_time_ms_ && packet_stream_it_->rtp.log_time_ms() > *end_time_ms_) { - return absl::nullopt; - } - return packet_stream_it_->rtp.log_time_ms(); - } - - absl::optional NextOutputEventTime() const override { - if (output_events_it_ == output_events_end_) { - return absl::nullopt; - } - if (end_time_ms_ && output_events_it_->log_time_ms() > *end_time_ms_) { - return absl::nullopt; - } - return output_events_it_->log_time_ms(); - } - - absl::optional NextSetMinimumDelayInfo() const override { - if (neteq_set_minimum_delay_events_it_ == - neteq_set_minimum_delay_events_end_) { - return absl::nullopt; - } - if (end_time_ms_ && - neteq_set_minimum_delay_events_it_->log_time_ms() > *end_time_ms_) { - return absl::nullopt; - } - return SetMinimumDelayInfo( - neteq_set_minimum_delay_events_it_->log_time_ms(), - neteq_set_minimum_delay_events_it_->minimum_delay_ms); - } - - std::unique_ptr PopPacket() override { - if (packet_stream_it_ == packet_stream_.end()) { - return std::unique_ptr(); - } - std::unique_ptr packet_data(new PacketData()); - packet_data->header = packet_stream_it_->rtp.header; - packet_data->time_ms = packet_stream_it_->rtp.log_time_ms(); - - // This is a header-only "dummy" packet. Set the payload to all zeros, with - // length according to the virtual length. - packet_data->payload.SetSize(packet_stream_it_->rtp.total_length - - packet_stream_it_->rtp.header_length); - std::fill_n(packet_data->payload.data(), packet_data->payload.size(), 0); - - ++packet_stream_it_; - return packet_data; - } - - void AdvanceOutputEvent() override { - if (output_events_it_ != output_events_end_) { - ++output_events_it_; - } - } - - void AdvanceSetMinimumDelay() override { - if (neteq_set_minimum_delay_events_it_ != - neteq_set_minimum_delay_events_end_) { - ++neteq_set_minimum_delay_events_it_; - } - } - - bool ended() const override { return !NextEventTime(); } - - absl::optional NextHeader() const override { - if (packet_stream_it_ == packet_stream_.end()) { - return absl::nullopt; - } - return packet_stream_it_->rtp.header; - } - - private: - const std::vector& packet_stream_; - std::vector::const_iterator packet_stream_it_; - std::vector::const_iterator output_events_it_; - const std::vector::const_iterator output_events_end_; - std::vector::const_iterator - neteq_set_minimum_delay_events_it_; - const std::vector::const_iterator - neteq_set_minimum_delay_events_end_; - const absl::optional end_time_ms_; -}; - namespace { // Factory to create a "replacement decoder" that produces the decoded audio @@ -323,16 +216,15 @@ class ReplacementAudioDecoderFactory : public AudioDecoderFactory { // the test and returns the NetEqDelayAnalyzer object that was used to // instrument the test. std::unique_ptr CreateNetEqTestAndRun( - const std::vector* packet_stream, - const std::vector* output_events, - const std::vector* - neteq_set_minimum_delay_events, - absl::optional end_time_ms, + ParsedRtcEventLog parsed_log, + uint32_t ssrc, const std::string& replacement_file_name, int file_sample_rate_hz) { - std::unique_ptr input( - new NetEqStreamInput(packet_stream, output_events, - neteq_set_minimum_delay_events, end_time_ms)); + std::unique_ptr input = + test::CreateNetEqEventLogInput(parsed_log, ssrc); + if (!input) { + return nullptr; + } constexpr int kReplacementPt = 127; std::set cn_types; @@ -373,47 +265,13 @@ NetEqStatsGetterMap SimulateNetEq(const ParsedRtcEventLog& parsed_log, const std::string& replacement_file_name, int file_sample_rate_hz) { NetEqStatsGetterMap neteq_stats; - - for (const auto& stream : parsed_log.incoming_rtp_packets_by_ssrc()) { - const uint32_t ssrc = stream.ssrc; - if (!IsAudioSsrc(parsed_log, kIncomingPacket, ssrc)) - continue; - const std::vector* audio_packets = - &stream.incoming_packets; - if (audio_packets == nullptr) { - // No incoming audio stream found. - continue; + for (uint32_t ssrc : parsed_log.incoming_audio_ssrcs()) { + std::unique_ptr stats = CreateNetEqTestAndRun( + parsed_log, ssrc, replacement_file_name, file_sample_rate_hz); + if (stats) { + neteq_stats[ssrc] = std::move(stats); } - - RTC_DCHECK(neteq_stats.find(ssrc) == neteq_stats.end()); - - std::map>::const_iterator - output_events_it = parsed_log.audio_playout_events().find(ssrc); - if (output_events_it == parsed_log.audio_playout_events().end()) { - // Could not find output events with SSRC matching the input audio stream. - // Using the first available stream of output events. - output_events_it = parsed_log.audio_playout_events().cbegin(); - } - - const auto neteq_set_minimum_delay_events_it = - parsed_log.neteq_set_minimum_delay_events().find(ssrc); - std::vector - empty_neteq_set_minimum_delay_event; - const std::vector& - neteq_set_minimum_delay_events = - neteq_set_minimum_delay_events_it == - parsed_log.neteq_set_minimum_delay_events().cend() - ? empty_neteq_set_minimum_delay_event - : neteq_set_minimum_delay_events_it->second; - - int64_t end_time_ms = parsed_log.first_log_segment().stop_time_ms(); - - neteq_stats[ssrc] = - CreateNetEqTestAndRun(audio_packets, &output_events_it->second, - &neteq_set_minimum_delay_events, end_time_ms, - replacement_file_name, file_sample_rate_hz); } - return neteq_stats; } diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer.cc index a5b8b49302176..07a7dd4104250 100644 --- a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer.cc +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/analyzer.cc @@ -46,6 +46,7 @@ #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" @@ -339,6 +340,72 @@ std::string GetDirectionAsShortString(PacketDirection direction) { } } +struct FakeExtensionSmall { + static constexpr RTPExtensionType kId = kRtpExtensionMid; + static constexpr absl::string_view Uri() { return "fake-extension-small"; } +}; +struct FakeExtensionLarge { + static constexpr RTPExtensionType kId = kRtpExtensionRtpStreamId; + static constexpr absl::string_view Uri() { return "fake-extension-large"; } +}; + +RtpPacketReceived RtpPacketForBWEFromHeader(const RTPHeader& header) { + RtpHeaderExtensionMap rtp_header_extensions(/*extmap_allow_mixed=*/true); + // ReceiveSideCongestionController doesn't need to know extensions ids as + // long as it able to get extensions by type. So any ids would work here. + rtp_header_extensions.Register(1); + rtp_header_extensions.Register(2); + rtp_header_extensions.Register(3); + rtp_header_extensions.Register(4); + // Use id > 14 to force two byte header per rtp header when this one is used. + rtp_header_extensions.Register(16); + + RtpPacketReceived rtp_packet(&rtp_header_extensions); + // Set only fields that might be relevant for the bandwidth estimatior. + rtp_packet.SetSsrc(header.ssrc); + rtp_packet.SetTimestamp(header.timestamp); + size_t num_bwe_extensions = 0; + if (header.extension.hasTransmissionTimeOffset) { + rtp_packet.SetExtension( + header.extension.transmissionTimeOffset); + ++num_bwe_extensions; + } + if (header.extension.hasAbsoluteSendTime) { + rtp_packet.SetExtension( + header.extension.absoluteSendTime); + ++num_bwe_extensions; + } + if (header.extension.hasTransportSequenceNumber) { + rtp_packet.SetExtension( + header.extension.transportSequenceNumber); + ++num_bwe_extensions; + } + + // All parts of the RTP header are 32bit aligned. + RTC_CHECK_EQ(header.headerLength % 4, 0); + + // Original packet could have more extensions, there could be csrcs that are + // not propagated by the rtc event log, i.e. logged header size might be + // larger that rtp_packet.header_size(). Increase it by setting an extra fake + // extension. + RTC_CHECK_GE(header.headerLength, rtp_packet.headers_size()); + size_t bytes_to_add = header.headerLength - rtp_packet.headers_size(); + if (bytes_to_add > 0) { + if (bytes_to_add <= 16) { + // one-byte header rtp header extension allows to add up to 16 bytes. + rtp_packet.AllocateExtension(FakeExtensionSmall::kId, bytes_to_add - 1); + } else { + // two-byte header rtp header extension would also add one byte per + // already set extension. + rtp_packet.AllocateExtension(FakeExtensionLarge::kId, + bytes_to_add - 2 - num_bwe_extensions); + } + } + RTC_CHECK_EQ(rtp_packet.headers_size(), header.headerLength); + + return rtp_packet; +} + } // namespace EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log, @@ -1468,12 +1535,16 @@ void EventLogAnalyzer::CreateReceiveSideBweSimulationGraph(Plot* plot) { int64_t last_update_us = 0; for (const auto& kv : incoming_rtp) { const RtpPacketType& packet = *kv.second; - int64_t arrival_time_ms = packet.rtp.log_time_us() / 1000; - size_t payload = packet.rtp.total_length; /*Should subtract header?*/ - clock.AdvanceTimeMicroseconds(packet.rtp.log_time_us() - - clock.TimeInMicroseconds()); - rscc.OnReceivedPacket(arrival_time_ms, payload, packet.rtp.header); - acked_bitrate.Update(payload, arrival_time_ms); + + RtpPacketReceived rtp_packet = RtpPacketForBWEFromHeader(packet.rtp.header); + rtp_packet.set_arrival_time(packet.rtp.log_time()); + rtp_packet.SetPayloadSize(packet.rtp.total_length - + rtp_packet.headers_size()); + + clock.AdvanceTime(rtp_packet.arrival_time() - clock.CurrentTime()); + rscc.OnReceivedPacket(rtp_packet, MediaType::VIDEO); + int64_t arrival_time_ms = packet.rtp.log_time().ms(); + acked_bitrate.Update(packet.rtp.total_length, arrival_time_ms); absl::optional bitrate_bps = acked_bitrate.Rate(arrival_time_ms); if (bitrate_bps) { uint32_t y = *bitrate_bps / 1000; diff --git a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/main.cc b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/main.cc index 4988808cabdb6..9fdc554cb53d2 100644 --- a/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/main.cc +++ b/third_party/libwebrtc/rtc_tools/rtc_event_log_visualizer/main.cc @@ -399,7 +399,7 @@ int main(int argc, char* argv[]) { "Fraction lost (outgoing RTCP)", "Loss rate (percent)", plot); }); auto GetCumulativeLost = [](const webrtc::rtcp::ReportBlock& block) -> float { - return block.cumulative_lost_signed(); + return block.cumulative_lost(); }; plots.RegisterPlot("incoming_rtcp_cumulative_lost", [&](Plot* plot) { analyzer.CreateSenderAndReceiverReportPlot( diff --git a/third_party/libwebrtc/rtc_tools/rtp_generator/rtp_generator.cc b/third_party/libwebrtc/rtc_tools/rtp_generator/rtp_generator.cc index e1a2cb30daadf..90af82abe52af 100644 --- a/third_party/libwebrtc/rtc_tools/rtp_generator/rtp_generator.cc +++ b/third_party/libwebrtc/rtc_tools/rtp_generator/rtp_generator.cc @@ -16,9 +16,16 @@ #include "api/task_queue/default_task_queue_factory.h" #include "api/test/create_frame_generator.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" #include "api/video_codecs/video_encoder.h" +#include "api/video_codecs/video_encoder_factory.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" #include "media/base/media_constants.h" #include "rtc_base/strings/json.h" #include "rtc_base/system/file_wrapper.h" @@ -164,8 +171,16 @@ absl::optional ParseRtpGeneratorOptionsFromFile( RtpGenerator::RtpGenerator(const RtpGeneratorOptions& options) : options_(options), - video_encoder_factory_(CreateBuiltinVideoEncoderFactory()), - video_decoder_factory_(CreateBuiltinVideoDecoderFactory()), + video_encoder_factory_( + std::make_unique>()), + video_decoder_factory_( + std::make_unique>()), video_bitrate_allocator_factory_( CreateBuiltinVideoBitrateAllocatorFactory()), event_log_(std::make_unique()), diff --git a/third_party/libwebrtc/rtc_tools/video_replay.cc b/third_party/libwebrtc/rtc_tools/video_replay.cc index 405948d8e0954..2600598cd9644 100644 --- a/third_party/libwebrtc/rtc_tools/video_replay.cc +++ b/third_party/libwebrtc/rtc_tools/video_replay.cc @@ -40,7 +40,6 @@ #include "system_wrappers/include/clock.h" #include "system_wrappers/include/sleep.h" #include "test/call_config_utils.h" -#include "test/call_test.h" #include "test/encoder_settings.h" #include "test/fake_decoder.h" #include "test/gtest.h" @@ -52,54 +51,55 @@ #include "test/testsupport/frame_writer.h" #include "test/time_controller/simulated_time_controller.h" #include "test/video_renderer.h" +#include "test/video_test_constants.h" // Flag for payload type. ABSL_FLAG(int, media_payload_type, - webrtc::test::CallTest::kPayloadTypeVP8, + webrtc::test::VideoTestConstants::kPayloadTypeVP8, "Media payload type"); // Flag for RED payload type. ABSL_FLAG(int, red_payload_type, - webrtc::test::CallTest::kRedPayloadType, + webrtc::test::VideoTestConstants::kRedPayloadType, "RED payload type"); // Flag for ULPFEC payload type. ABSL_FLAG(int, ulpfec_payload_type, - webrtc::test::CallTest::kUlpfecPayloadType, + webrtc::test::VideoTestConstants::kUlpfecPayloadType, "ULPFEC payload type"); // Flag for FLEXFEC payload type. ABSL_FLAG(int, flexfec_payload_type, - webrtc::test::CallTest::kFlexfecPayloadType, + webrtc::test::VideoTestConstants::kFlexfecPayloadType, "FLEXFEC payload type"); ABSL_FLAG(int, media_payload_type_rtx, - webrtc::test::CallTest::kSendRtxPayloadType, + webrtc::test::VideoTestConstants::kSendRtxPayloadType, "Media over RTX payload type"); ABSL_FLAG(int, red_payload_type_rtx, - webrtc::test::CallTest::kRtxRedPayloadType, + webrtc::test::VideoTestConstants::kRtxRedPayloadType, "RED over RTX payload type"); // Flag for SSRC and RTX SSRC. ABSL_FLAG(uint32_t, ssrc, - webrtc::test::CallTest::kVideoSendSsrcs[0], + webrtc::test::VideoTestConstants::kVideoSendSsrcs[0], "Incoming SSRC"); ABSL_FLAG(uint32_t, ssrc_rtx, - webrtc::test::CallTest::kSendRtxSsrcs[0], + webrtc::test::VideoTestConstants::kSendRtxSsrcs[0], "Incoming RTX SSRC"); ABSL_FLAG(uint32_t, ssrc_flexfec, - webrtc::test::CallTest::kFlexfecSendSsrc, + webrtc::test::VideoTestConstants::kFlexfecSendSsrc, "Incoming FLEXFEC SSRC"); // Flag for abs-send-time id. diff --git a/third_party/libwebrtc/sdk/BUILD.gn b/third_party/libwebrtc/sdk/BUILD.gn index d8fcb6a61e7eb..bef4521dc6884 100644 --- a/third_party/libwebrtc/sdk/BUILD.gn +++ b/third_party/libwebrtc/sdk/BUILD.gn @@ -230,6 +230,9 @@ if (is_ios || is_mac) { "objc/native/api/audio_device_module.h", "objc/native/api/audio_device_module.mm", ] + if (is_mac) { + frameworks = [ "AudioUnit.framework" ] + } deps = [ ":audio_device", @@ -290,6 +293,9 @@ if (is_ios || is_mac) { absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ] frameworks = [ "AudioToolbox.framework" ] + if (is_mac) { + frameworks += [ "AudioUnit.framework" ] + } } # This target exists to expose :audio_session_objc and @@ -430,6 +436,9 @@ if (is_ios || is_mac) { "../rtc_base:threading", "../rtc_base:timeutils", ] + if (is_mac) { + frameworks = [ "AudioUnit.framework" ] + } } rtc_library("objc_audio_device_module") { @@ -447,6 +456,9 @@ if (is_ios || is_mac) { "../modules/audio_device:audio_device_api", "../rtc_base:logging", ] + if (is_mac) { + frameworks = [ "AudioUnit.framework" ] + } } if (!build_with_mozilla) { @@ -1598,6 +1610,7 @@ if (is_ios || is_mac) { "../api/video:video_rtp_headers", "../api/video_codecs:video_codecs_api", "../common_video", + "../pc:video_track_source_proxy", "../rtc_base:buffer", "../rtc_base:logging", "../rtc_base:ssl", diff --git a/third_party/libwebrtc/sdk/android/api/org/webrtc/YuvHelper.java b/third_party/libwebrtc/sdk/android/api/org/webrtc/YuvHelper.java index afb8e837d11ca..e5ddb6164506a 100644 --- a/third_party/libwebrtc/sdk/android/api/org/webrtc/YuvHelper.java +++ b/third_party/libwebrtc/sdk/android/api/org/webrtc/YuvHelper.java @@ -36,8 +36,8 @@ public static void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, in final int dstStartU = dstStartY + dstStrideY * dstSliceHeightY; final int dstEndU = dstStartU + dstStrideU * chromaHeight; final int dstStartV = dstStartU + dstStrideU * dstSliceHeightU; - // The last line doesn't need any padding, so use chromaWidth - // to calculate the exact end position. + // The last line doesn't need any padding, so use chromaWidth to calculate the exact end + // position. final int dstEndV = dstStartV + dstStrideU * (chromaHeight - 1) + chromaWidth; if (dst.capacity() < dstEndV) { throw new IllegalArgumentException("Expected destination buffer capacity to be at least " @@ -65,6 +65,14 @@ public static void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, in dstWidth, dstHeight, (dstWidth + 1) / 2, (dstHeight + 1) / 2); } + /** Helper method for copying I420 to buffer with the given stride and slice height. */ + public static void I420Copy(ByteBuffer srcY, int srcStrideY, ByteBuffer srcU, int srcStrideU, + ByteBuffer srcV, int srcStrideV, ByteBuffer dst, int dstWidth, int dstHeight, int dstStride, + int dstSliceHeight) { + I420Copy(srcY, srcStrideY, srcU, srcStrideU, srcV, srcStrideV, dst, dstWidth, dstHeight, + dstStride, dstSliceHeight, (dstStride + 1) / 2, (dstSliceHeight + 1) / 2); + } + /** * Copy I420 Buffer to a contiguously allocated buffer. * @param dstStrideY the stride of output buffers' Y plane. diff --git a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java index ad40898e4c208..47cb5689ced44 100644 --- a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java +++ b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/AndroidVideoDecoder.java @@ -26,20 +26,9 @@ /** * Android hardware video decoder. */ -@SuppressWarnings("deprecation") -// Cannot support API 16 without using deprecated methods. -// TODO(sakal): Rename to MediaCodecVideoDecoder once the deprecated implementation is removed. class AndroidVideoDecoder implements VideoDecoder, VideoSink { private static final String TAG = "AndroidVideoDecoder"; - // TODO(magjed): Use MediaFormat.KEY_* constants when part of the public API. - private static final String MEDIA_FORMAT_KEY_STRIDE = "stride"; - private static final String MEDIA_FORMAT_KEY_SLICE_HEIGHT = "slice-height"; - private static final String MEDIA_FORMAT_KEY_CROP_LEFT = "crop-left"; - private static final String MEDIA_FORMAT_KEY_CROP_RIGHT = "crop-right"; - private static final String MEDIA_FORMAT_KEY_CROP_TOP = "crop-top"; - private static final String MEDIA_FORMAT_KEY_CROP_BOTTOM = "crop-bottom"; - // MediaCodec.release() occasionally hangs. Release stops waiting and reports failure after // this timeout. private static final int MEDIA_CODEC_RELEASE_TIMEOUT_MS = 5000; @@ -162,7 +151,7 @@ private VideoCodecStatus initDecodeInternal(int width, int height) { decoderThreadChecker.checkIsOnValidThread(); Logging.d(TAG, "initDecodeInternal name: " + codecName + " type: " + codecType + " width: " + width - + " height: " + height); + + " height: " + height + " color format: " + colorFormat); if (outputThread != null) { Logging.e(TAG, "initDecodeInternal called while the codec is already running"); return VideoCodecStatus.FALLBACK_SOFTWARE; @@ -568,17 +557,17 @@ private VideoFrame.Buffer copyI420Buffer( private void reformat(MediaFormat format) { outputThreadChecker.checkIsOnValidThread(); - Logging.d(TAG, "Decoder format changed: " + format.toString()); + Logging.d(TAG, "Decoder format changed: " + format); final int newWidth; final int newHeight; - if (format.containsKey(MEDIA_FORMAT_KEY_CROP_LEFT) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_RIGHT) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_BOTTOM) - && format.containsKey(MEDIA_FORMAT_KEY_CROP_TOP)) { - newWidth = 1 + format.getInteger(MEDIA_FORMAT_KEY_CROP_RIGHT) - - format.getInteger(MEDIA_FORMAT_KEY_CROP_LEFT); - newHeight = 1 + format.getInteger(MEDIA_FORMAT_KEY_CROP_BOTTOM) - - format.getInteger(MEDIA_FORMAT_KEY_CROP_TOP); + if (format.containsKey(MediaFormat.KEY_CROP_LEFT) + && format.containsKey(MediaFormat.KEY_CROP_RIGHT) + && format.containsKey(MediaFormat.KEY_CROP_BOTTOM) + && format.containsKey(MediaFormat.KEY_CROP_TOP)) { + newWidth = 1 + format.getInteger(MediaFormat.KEY_CROP_RIGHT) + - format.getInteger(MediaFormat.KEY_CROP_LEFT); + newHeight = 1 + format.getInteger(MediaFormat.KEY_CROP_BOTTOM) + - format.getInteger(MediaFormat.KEY_CROP_TOP); } else { newWidth = format.getInteger(MediaFormat.KEY_WIDTH); newHeight = format.getInteger(MediaFormat.KEY_HEIGHT); @@ -615,11 +604,11 @@ private void reformat(MediaFormat format) { // Save stride and sliceHeight under the dimension lock. synchronized (dimensionLock) { - if (format.containsKey(MEDIA_FORMAT_KEY_STRIDE)) { - stride = format.getInteger(MEDIA_FORMAT_KEY_STRIDE); + if (format.containsKey(MediaFormat.KEY_STRIDE)) { + stride = format.getInteger(MediaFormat.KEY_STRIDE); } - if (format.containsKey(MEDIA_FORMAT_KEY_SLICE_HEIGHT)) { - sliceHeight = format.getInteger(MEDIA_FORMAT_KEY_SLICE_HEIGHT); + if (format.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) { + sliceHeight = format.getInteger(MediaFormat.KEY_SLICE_HEIGHT); } Logging.d(TAG, "Frame stride and slice height: " + stride + " x " + sliceHeight); stride = Math.max(width, stride); diff --git a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java index 41d97359eb8fd..94dfdf0728bc9 100644 --- a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java +++ b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java @@ -10,8 +10,13 @@ package org.webrtc; +import static android.media.MediaCodecInfo.CodecProfileLevel.AVCLevel3; +import static android.media.MediaCodecInfo.CodecProfileLevel.AVCProfileHigh; +import static android.media.MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR; + import android.media.MediaCodec; import android.media.MediaCodecInfo; +import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaFormat; import android.opengl.GLES20; import android.os.Build; @@ -32,16 +37,6 @@ class HardwareVideoEncoder implements VideoEncoder { private static final String TAG = "HardwareVideoEncoder"; - // Bitrate modes - should be in sync with OMX_VIDEO_CONTROLRATETYPE defined - // in OMX_Video.h - private static final int VIDEO_ControlRateConstant = 2; - // Key associated with the bitrate control mode value (above). Not present as a MediaFormat - // constant until API level 21. - private static final String KEY_BITRATE_MODE = "bitrate-mode"; - - private static final int VIDEO_AVC_PROFILE_HIGH = 8; - private static final int VIDEO_AVC_LEVEL_3 = 0x100; - private static final int MAX_VIDEO_FRAMERATE = 30; // See MAX_ENCODER_Q_SIZE in androidmediaencoder.cc. @@ -105,7 +100,6 @@ public void waitForZero() { private final VideoCodecMimeType codecType; private final Integer surfaceColorFormat; private final Integer yuvColorFormat; - private final YuvFormat yuvFormat; private final Map params; private final int keyFrameIntervalSec; // Base interval for generating key frames. // Interval at which to force a key frame. Used to reduce color distortions caused by some @@ -148,6 +142,10 @@ public void waitForZero() { private int stride; // Y-plane slice-height in the encoder's input private int sliceHeight; + // True if encoder input color format is semi-planar (NV12). + private boolean isSemiPlanar; + // Size of frame for current color format and stride, in bytes. + private int frameSizeBytes; private boolean useSurfaceMode; // --- Only accessed from the encoding thread. @@ -168,6 +166,9 @@ public void waitForZero() { // value to send exceptions thrown during release back to the encoder thread. @Nullable private volatile Exception shutdownException; + // True if collection of encoding statistics is enabled. + private boolean isEncodingStatisticsEnabled; + /** * Creates a new HardwareVideoEncoder with the given codecName, codecType, colorFormat, key frame * intervals, and bitrateAdjuster. @@ -192,7 +193,6 @@ public HardwareVideoEncoder(MediaCodecWrapperFactory mediaCodecWrapperFactory, S this.codecType = codecType; this.surfaceColorFormat = surfaceColorFormat; this.yuvColorFormat = yuvColorFormat; - this.yuvFormat = YuvFormat.valueOf(yuvColorFormat); this.params = params; this.keyFrameIntervalSec = keyFrameIntervalSec; this.forcedKeyFrameNs = TimeUnit.MILLISECONDS.toNanos(forceKeyFrameIntervalMs); @@ -220,8 +220,9 @@ public VideoCodecStatus initEncode(Settings settings, Callback callback) { adjustedBitrate = bitrateAdjuster.getAdjustedBitrateBps(); Logging.d(TAG, - "initEncode: " + width + " x " + height + ". @ " + settings.startBitrate - + "kbps. Fps: " + settings.maxFramerate + " Use surface mode: " + useSurfaceMode); + "initEncode name: " + codecName + " type: " + codecType + " width: " + width + + " height: " + height + " framerate_fps: " + settings.maxFramerate + + " bitrate_kbps: " + settings.startBitrate + " surface mode: " + useSurfaceMode); return initEncodeInternal(); } @@ -231,6 +232,8 @@ private VideoCodecStatus initEncodeInternal() { nextPresentationTimestampUs = 0; lastKeyFrameNs = -1; + isEncodingStatisticsEnabled = false; + try { codec = mediaCodecWrapperFactory.createByCodecName(codecName); } catch (IOException | IllegalArgumentException e) { @@ -242,7 +245,7 @@ private VideoCodecStatus initEncodeInternal() { try { MediaFormat format = MediaFormat.createVideoFormat(codecType.mimeType(), width, height); format.setInteger(MediaFormat.KEY_BIT_RATE, adjustedBitrate); - format.setInteger(KEY_BITRATE_MODE, VIDEO_ControlRateConstant); + format.setInteger(MediaFormat.KEY_BITRATE_MODE, BITRATE_MODE_CBR); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); format.setFloat( MediaFormat.KEY_FRAME_RATE, (float) bitrateAdjuster.getAdjustedFramerateFps()); @@ -254,8 +257,8 @@ private VideoCodecStatus initEncodeInternal() { } switch (profileLevelId) { case VideoCodecInfo.H264_CONSTRAINED_HIGH_3_1: - format.setInteger("profile", VIDEO_AVC_PROFILE_HIGH); - format.setInteger("level", VIDEO_AVC_LEVEL_3); + format.setInteger("profile", AVCProfileHigh); + format.setInteger("level", AVCLevel3); break; case VideoCodecInfo.H264_CONSTRAINED_BASELINE_3_1: break; @@ -263,6 +266,18 @@ private VideoCodecStatus initEncodeInternal() { Logging.w(TAG, "Unknown profile level id: " + profileLevelId); } } + + if (codecName.equals("c2.google.av1.encoder")) { + // Enable RTC mode in AV1 HW encoder. + format.setInteger("vendor.google-av1enc.encoding-preset.int32.value", 1); + } + + if (isEncodingStatisticsSupported()) { + format.setInteger(MediaFormat.KEY_VIDEO_ENCODING_STATISTICS_LEVEL, + MediaFormat.VIDEO_ENCODING_STATISTICS_LEVEL_1); + isEncodingStatisticsEnabled = true; + } + Logging.d(TAG, "Format: " + format); codec.configure( format, null /* surface */, null /* crypto */, MediaCodec.CONFIGURE_FLAG_ENCODE); @@ -274,9 +289,7 @@ private VideoCodecStatus initEncodeInternal() { textureEglBase.makeCurrent(); } - MediaFormat inputFormat = codec.getInputFormat(); - stride = getStride(inputFormat, width); - sliceHeight = getSliceHeight(inputFormat, height); + updateInputFormat(codec.getInputFormat()); codec.start(); } catch (IllegalStateException e) { @@ -343,8 +356,7 @@ public VideoCodecStatus encode(VideoFrame videoFrame, EncodeInfo encodeInfo) { return VideoCodecStatus.UNINITIALIZED; } - final VideoFrame.Buffer videoFrameBuffer = videoFrame.getBuffer(); - final boolean isTextureBuffer = videoFrameBuffer instanceof VideoFrame.TextureBuffer; + final boolean isTextureBuffer = videoFrame.getBuffer() instanceof VideoFrame.TextureBuffer; // If input resolution changed, restart the codec with the new resolution. final int frameWidth = videoFrame.getBuffer().getWidth(); @@ -374,9 +386,6 @@ public VideoCodecStatus encode(VideoFrame videoFrame, EncodeInfo encodeInfo) { requestKeyFrame(videoFrame.getTimestampNs()); } - // Number of bytes in the video buffer. Y channel is sampled at one byte per pixel; U and V are - // subsampled at one byte per four pixels. - int bufferSize = videoFrameBuffer.getHeight() * videoFrameBuffer.getWidth() * 3 / 2; EncodedImage.Builder builder = EncodedImage.builder() .setCaptureTimeNs(videoFrame.getTimestampNs()) .setEncodedWidth(videoFrame.getBuffer().getWidth()) @@ -394,8 +403,7 @@ public VideoCodecStatus encode(VideoFrame videoFrame, EncodeInfo encodeInfo) { if (useSurfaceMode) { returnValue = encodeTextureBuffer(videoFrame, presentationTimestampUs); } else { - returnValue = - encodeByteBuffer(videoFrame, presentationTimestampUs, videoFrameBuffer, bufferSize); + returnValue = encodeByteBuffer(videoFrame, presentationTimestampUs); } // Check if the queue was successful. @@ -426,8 +434,7 @@ private VideoCodecStatus encodeTextureBuffer( return VideoCodecStatus.OK; } - private VideoCodecStatus encodeByteBuffer(VideoFrame videoFrame, long presentationTimestampUs, - VideoFrame.Buffer videoFrameBuffer, int bufferSize) { + private VideoCodecStatus encodeByteBuffer(VideoFrame videoFrame, long presentationTimestampUs) { encodeThreadChecker.checkIsOnValidThread(); // No timeout. Don't block for an input buffer, drop frames if the encoder falls behind. int index; @@ -451,11 +458,19 @@ private VideoCodecStatus encodeByteBuffer(VideoFrame videoFrame, long presentati Logging.e(TAG, "getInputBuffer with index=" + index + " failed", e); return VideoCodecStatus.ERROR; } - fillInputBuffer(buffer, videoFrameBuffer); + + if (buffer.capacity() < frameSizeBytes) { + Logging.e(TAG, + "Input buffer size: " + buffer.capacity() + + " is smaller than frame size: " + frameSizeBytes); + return VideoCodecStatus.ERROR; + } + + fillInputBuffer(buffer, videoFrame.getBuffer()); try { codec.queueInputBuffer( - index, 0 /* offset */, bufferSize, presentationTimestampUs, 0 /* flags */); + index, 0 /* offset */, frameSizeBytes, presentationTimestampUs, 0 /* flags */); } catch (IllegalStateException e) { Logging.e(TAG, "queueInputBuffer failed", e); // IllegalStateException thrown when the codec is in the wrong state. @@ -571,66 +586,84 @@ protected void deliverEncodedImage() { return; } - ByteBuffer codecOutputBuffer = codec.getOutputBuffer(index); - codecOutputBuffer.position(info.offset); - codecOutputBuffer.limit(info.offset + info.size); + ByteBuffer outputBuffer = codec.getOutputBuffer(index); + outputBuffer.position(info.offset); + outputBuffer.limit(info.offset + info.size); if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { Logging.d(TAG, "Config frame generated. Offset: " + info.offset + ". Size: " + info.size); - configBuffer = ByteBuffer.allocateDirect(info.size); - configBuffer.put(codecOutputBuffer); - } else { - bitrateAdjuster.reportEncodedFrame(info.size); - if (adjustedBitrate != bitrateAdjuster.getAdjustedBitrateBps()) { - updateBitrate(); + if (info.size > 0 + && (codecType == VideoCodecMimeType.H264 || codecType == VideoCodecMimeType.H265)) { + // In case of H264 and H265 config buffer contains SPS and PPS headers. Presence of these + // headers makes IDR frame a truly keyframe. Some encoders issue IDR frames without SPS + // and PPS. We save config buffer here to prepend it to all IDR frames encoder delivers. + configBuffer = ByteBuffer.allocateDirect(info.size); + configBuffer.put(outputBuffer); } + return; + } - final boolean isKeyFrame = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0; - if (isKeyFrame) { - Logging.d(TAG, "Sync frame generated"); - } + bitrateAdjuster.reportEncodedFrame(info.size); + if (adjustedBitrate != bitrateAdjuster.getAdjustedBitrateBps()) { + updateBitrate(); + } - final ByteBuffer frameBuffer; - if (isKeyFrame && codecType == VideoCodecMimeType.H264) { - Logging.d(TAG, - "Prepending config frame of size " + configBuffer.capacity() - + " to output buffer with offset " + info.offset + ", size " + info.size); - // For H.264 key frame prepend SPS and PPS NALs at the start. - frameBuffer = ByteBuffer.allocateDirect(info.size + configBuffer.capacity()); - configBuffer.rewind(); - frameBuffer.put(configBuffer); - frameBuffer.put(codecOutputBuffer); - frameBuffer.rewind(); - } else { - frameBuffer = codecOutputBuffer.slice(); - } + final boolean isKeyFrame = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0; + if (isKeyFrame) { + Logging.d(TAG, "Sync frame generated"); + } - final EncodedImage.FrameType frameType = isKeyFrame - ? EncodedImage.FrameType.VideoFrameKey - : EncodedImage.FrameType.VideoFrameDelta; + // Extract QP before releasing output buffer. + Integer qp = null; + if (isEncodingStatisticsEnabled) { + MediaFormat format = codec.getOutputFormat(index); + if (format != null && format.containsKey(MediaFormat.KEY_VIDEO_QP_AVERAGE)) { + qp = format.getInteger(MediaFormat.KEY_VIDEO_QP_AVERAGE); + } + } + final ByteBuffer frameBuffer; + final Runnable releaseCallback; + if (isKeyFrame && configBuffer != null) { + Logging.d(TAG, + "Prepending config buffer of size " + configBuffer.capacity() + + " to output buffer with offset " + info.offset + ", size " + info.size); + frameBuffer = ByteBuffer.allocateDirect(info.size + configBuffer.capacity()); + configBuffer.rewind(); + frameBuffer.put(configBuffer); + frameBuffer.put(outputBuffer); + frameBuffer.rewind(); + codec.releaseOutputBuffer(index, /* render= */ false); + releaseCallback = null; + } else { + frameBuffer = outputBuffer.slice(); outputBuffersBusyCount.increment(); - EncodedImage.Builder builder = outputBuilders.poll(); - EncodedImage encodedImage = builder - .setBuffer(frameBuffer, - () -> { - // This callback should not throw any exceptions since - // it may be called on an arbitrary thread. - // Check bug webrtc:11230 for more details. - try { - codec.releaseOutputBuffer(index, false); - } catch (Exception e) { - Logging.e(TAG, "releaseOutputBuffer failed", e); - } - outputBuffersBusyCount.decrement(); - }) - .setFrameType(frameType) - .createEncodedImage(); - // TODO(mellem): Set codec-specific info. - callback.onEncodedFrame(encodedImage, new CodecSpecificInfo()); - // Note that the callback may have retained the image. - encodedImage.release(); + releaseCallback = () -> { + // This callback should not throw any exceptions since + // it may be called on an arbitrary thread. + // Check bug webrtc:11230 for more details. + try { + codec.releaseOutputBuffer(index, /* render= */ false); + } catch (Exception e) { + Logging.e(TAG, "releaseOutputBuffer failed", e); + } + outputBuffersBusyCount.decrement(); + }; } + + final EncodedImage.FrameType frameType = isKeyFrame ? EncodedImage.FrameType.VideoFrameKey + : EncodedImage.FrameType.VideoFrameDelta; + + EncodedImage.Builder builder = outputBuilders.poll(); + builder.setBuffer(frameBuffer, releaseCallback); + builder.setFrameType(frameType); + builder.setQp(qp); + + EncodedImage encodedImage = builder.createEncodedImage(); + // TODO(mellem): Set codec-specific info. + callback.onEncodedFrame(encodedImage, new CodecSpecificInfo()); + // Note that the callback may have retained the image. + encodedImage.release(); } catch (IllegalStateException e) { Logging.e(TAG, "deliverOutput failed", e); } @@ -674,78 +707,87 @@ private boolean canUseSurface() { return sharedContext != null && surfaceColorFormat != null; } - private static int getStride(MediaFormat inputFormat, int width) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && inputFormat != null - && inputFormat.containsKey(MediaFormat.KEY_STRIDE)) { - return inputFormat.getInteger(MediaFormat.KEY_STRIDE); + /** Fetches stride and slice height from input media format */ + private void updateInputFormat(MediaFormat format) { + stride = width; + sliceHeight = height; + + if (format != null) { + if (format.containsKey(MediaFormat.KEY_STRIDE)) { + stride = format.getInteger(MediaFormat.KEY_STRIDE); + stride = Math.max(stride, width); + } + + if (format.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) { + sliceHeight = format.getInteger(MediaFormat.KEY_SLICE_HEIGHT); + sliceHeight = Math.max(sliceHeight, height); + } + } + + isSemiPlanar = isSemiPlanar(yuvColorFormat); + if (isSemiPlanar) { + int chromaHeight = (height + 1) / 2; + frameSizeBytes = sliceHeight * stride + chromaHeight * stride; + } else { + int chromaStride = (stride + 1) / 2; + int chromaSliceHeight = (sliceHeight + 1) / 2; + frameSizeBytes = sliceHeight * stride + chromaSliceHeight * chromaStride * 2; } - return width; + + Logging.d(TAG, + "updateInputFormat format: " + format + " stride: " + stride + + " sliceHeight: " + sliceHeight + " isSemiPlanar: " + isSemiPlanar + + " frameSizeBytes: " + frameSizeBytes); } - private static int getSliceHeight(MediaFormat inputFormat, int height) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && inputFormat != null - && inputFormat.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) { - return inputFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT); + protected boolean isEncodingStatisticsSupported() { + // WebRTC quality scaler, which adjusts resolution and/or frame rate based on encoded QP, + // expects QP to be in native bitstream range for given codec. Native QP range for VP8 is + // [0, 127] and for VP9 is [0, 255]. MediaCodec VP8 and VP9 encoders (perhaps not all) + // return QP in range [0, 64], which is libvpx API specific range. Due to this mismatch we + // can't use QP feedback from these codecs. + if (codecType == VideoCodecMimeType.VP8 || codecType == VideoCodecMimeType.VP9) { + return false; } - return height; + + MediaCodecInfo codecInfo = codec.getCodecInfo(); + if (codecInfo == null) { + return false; + } + + CodecCapabilities codecCaps = codecInfo.getCapabilitiesForType(codecType.mimeType()); + if (codecCaps == null) { + return false; + } + + return codecCaps.isFeatureSupported(CodecCapabilities.FEATURE_EncodingStatistics); } // Visible for testing. - protected void fillInputBuffer(ByteBuffer buffer, VideoFrame.Buffer videoFrameBuffer) { - yuvFormat.fillBuffer(buffer, videoFrameBuffer, stride, sliceHeight); + protected void fillInputBuffer(ByteBuffer buffer, VideoFrame.Buffer frame) { + VideoFrame.I420Buffer i420 = frame.toI420(); + if (isSemiPlanar) { + YuvHelper.I420ToNV12(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(), + i420.getDataV(), i420.getStrideV(), buffer, i420.getWidth(), i420.getHeight(), stride, + sliceHeight); + } else { + YuvHelper.I420Copy(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(), + i420.getDataV(), i420.getStrideV(), buffer, i420.getWidth(), i420.getHeight(), stride, + sliceHeight); + } + i420.release(); } - /** - * Enumeration of supported YUV color formats used for MediaCodec's input. - */ - private enum YuvFormat { - I420 { - @Override - void fillBuffer( - ByteBuffer dstBuffer, VideoFrame.Buffer srcBuffer, int dstStrideY, int dstSliceHeightY) { - /* - * According to the docs in Android MediaCodec, the stride of the U and V planes can be - * calculated based on the color format, though it is generally undefined and depends on the - * device and release. - *

Assuming the width and height, dstStrideY and dstSliceHeightY are - * even, it works fine when we define the stride and slice-height of the dst U/V plane to be - * half of the dst Y plane. - */ - int dstStrideU = dstStrideY / 2; - int dstSliceHeight = dstSliceHeightY / 2; - VideoFrame.I420Buffer i420 = srcBuffer.toI420(); - YuvHelper.I420Copy(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(), - i420.getDataV(), i420.getStrideV(), dstBuffer, i420.getWidth(), i420.getHeight(), - dstStrideY, dstSliceHeightY, dstStrideU, dstSliceHeight); - i420.release(); - } - }, - NV12 { - @Override - void fillBuffer( - ByteBuffer dstBuffer, VideoFrame.Buffer srcBuffer, int dstStrideY, int dstSliceHeightY) { - VideoFrame.I420Buffer i420 = srcBuffer.toI420(); - YuvHelper.I420ToNV12(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(), - i420.getDataV(), i420.getStrideV(), dstBuffer, i420.getWidth(), i420.getHeight(), - dstStrideY, dstSliceHeightY); - i420.release(); - } - }; - - abstract void fillBuffer( - ByteBuffer dstBuffer, VideoFrame.Buffer srcBuffer, int dstStrideY, int dstSliceHeightY); - - static YuvFormat valueOf(int colorFormat) { - switch (colorFormat) { - case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar: - return I420; - case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar: - case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar: - case MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m: - return NV12; - default: - throw new IllegalArgumentException("Unsupported colorFormat: " + colorFormat); - } + protected boolean isSemiPlanar(int colorFormat) { + switch (colorFormat) { + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar: + return false; + case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar: + case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar: + case MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m: + return true; + default: + throw new IllegalArgumentException("Unsupported colorFormat: " + colorFormat); } } } diff --git a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java index 60c853df35916..11e0f58dfe328 100644 --- a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java +++ b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapper.java @@ -11,6 +11,7 @@ package org.webrtc; import android.media.MediaCodec; +import android.media.MediaCodecInfo; import android.media.MediaCrypto; import android.media.MediaFormat; import android.os.Bundle; @@ -45,6 +46,8 @@ interface MediaCodecWrapper { MediaFormat getOutputFormat(); + MediaFormat getOutputFormat(int index); + ByteBuffer getInputBuffer(int index); ByteBuffer getOutputBuffer(int index); @@ -52,4 +55,6 @@ interface MediaCodecWrapper { Surface createInputSurface(); void setParameters(Bundle params); + + MediaCodecInfo getCodecInfo(); } diff --git a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java index 2ba62ac7d6cde..207492f31cd97 100644 --- a/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java +++ b/third_party/libwebrtc/sdk/android/src/java/org/webrtc/MediaCodecWrapperFactoryImpl.java @@ -12,6 +12,7 @@ import android.media.MediaCodec; import android.media.MediaCodec.BufferInfo; +import android.media.MediaCodecInfo; import android.media.MediaCrypto; import android.media.MediaFormat; import android.os.Bundle; @@ -87,6 +88,11 @@ public MediaFormat getOutputFormat() { return mediaCodec.getOutputFormat(); } + @Override + public MediaFormat getOutputFormat(int index) { + return mediaCodec.getOutputFormat(index); + } + @Override public ByteBuffer getInputBuffer(int index) { return mediaCodec.getInputBuffer(index); @@ -106,6 +112,11 @@ public Surface createInputSurface() { public void setParameters(Bundle params) { mediaCodec.setParameters(params); } + + @Override + public MediaCodecInfo getCodecInfo() { + return mediaCodec.getCodecInfo(); + } } @Override diff --git a/third_party/libwebrtc/sdk/media_constraints.h b/third_party/libwebrtc/sdk/media_constraints.h index c946e4fab1dd1..a428abdce0443 100644 --- a/third_party/libwebrtc/sdk/media_constraints.h +++ b/third_party/libwebrtc/sdk/media_constraints.h @@ -17,6 +17,7 @@ #define SDK_MEDIA_CONSTRAINTS_H_ #include + #include #include #include @@ -59,10 +60,10 @@ class MediaConstraints { // These keys are google specific. static const char kGoogEchoCancellation[]; // googEchoCancellation - static const char kAutoGainControl[]; // googAutoGainControl - static const char kNoiseSuppression[]; // googNoiseSuppression - static const char kHighpassFilter[]; // googHighpassFilter - static const char kAudioMirroring[]; // googAudioMirroring + static const char kAutoGainControl[]; // googAutoGainControl + static const char kNoiseSuppression[]; // googNoiseSuppression + static const char kHighpassFilter[]; // googHighpassFilter + static const char kAudioMirroring[]; // googAudioMirroring static const char kAudioNetworkAdaptorConfig[]; // googAudioNetworkAdaptorConfig static const char kInitAudioRecordingOnSend[]; // InitAudioRecordingOnSend; diff --git a/third_party/libwebrtc/sdk/objc/api/logging/RTCCallbackLogger.h b/third_party/libwebrtc/sdk/objc/api/logging/RTCCallbackLogger.h index c1aeb825cb740..1d178b6d49142 100644 --- a/third_party/libwebrtc/sdk/objc/api/logging/RTCCallbackLogger.h +++ b/third_party/libwebrtc/sdk/objc/api/logging/RTCCallbackLogger.h @@ -32,7 +32,7 @@ RTC_OBJC_EXPORT // to implement dispatching to some other queue. - (void)start:(nullable RTCCallbackLoggerMessageHandler)handler; - (void)startWithMessageAndSeverityHandler: - (nullable RTCCallbackLoggerMessageAndSeverityHandler)handler; + (nullable RTCCallbackLoggerMessageAndSeverityHandler)handler; - (void)stop; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h index 70a6532dbccf3..6ad780acdc0aa 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCConfiguration+Private.h @@ -21,39 +21,39 @@ NS_ASSUME_NONNULL_BEGIN : (RTCIceTransportPolicy)policy; + (RTCIceTransportPolicy)transportPolicyForTransportsType: - (webrtc::PeerConnectionInterface::IceTransportsType)nativeType; + (webrtc::PeerConnectionInterface::IceTransportsType)nativeType; + (NSString *)stringForTransportPolicy:(RTCIceTransportPolicy)policy; + (webrtc::PeerConnectionInterface::BundlePolicy)nativeBundlePolicyForPolicy: - (RTCBundlePolicy)policy; + (RTCBundlePolicy)policy; + (RTCBundlePolicy)bundlePolicyForNativePolicy: - (webrtc::PeerConnectionInterface::BundlePolicy)nativePolicy; + (webrtc::PeerConnectionInterface::BundlePolicy)nativePolicy; + (NSString *)stringForBundlePolicy:(RTCBundlePolicy)policy; + (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativeRtcpMuxPolicyForPolicy: - (RTCRtcpMuxPolicy)policy; + (RTCRtcpMuxPolicy)policy; + (RTCRtcpMuxPolicy)rtcpMuxPolicyForNativePolicy: - (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativePolicy; + (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativePolicy; + (NSString *)stringForRtcpMuxPolicy:(RTCRtcpMuxPolicy)policy; + (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativeTcpCandidatePolicyForPolicy: - (RTCTcpCandidatePolicy)policy; + (RTCTcpCandidatePolicy)policy; + (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy: - (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy; + (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy; + (NSString *)stringForTcpCandidatePolicy:(RTCTcpCandidatePolicy)policy; + (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativeCandidateNetworkPolicyForPolicy: - (RTCCandidateNetworkPolicy)policy; + (RTCCandidateNetworkPolicy)policy; + (RTCCandidateNetworkPolicy)candidateNetworkPolicyForNativePolicy: - (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativePolicy; + (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativePolicy; + (NSString *)stringForCandidateNetworkPolicy:(RTCCandidateNetworkPolicy)policy; @@ -72,7 +72,7 @@ NS_ASSUME_NONNULL_BEGIN - (nullable webrtc::PeerConnectionInterface::RTCConfiguration *)createNativeConfiguration; - (instancetype)initWithNativeConfiguration: - (const webrtc::PeerConnectionInterface::RTCConfiguration &)config NS_DESIGNATED_INITIALIZER; + (const webrtc::PeerConnectionInterface::RTCConfiguration &)config NS_DESIGNATED_INITIALIZER; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h index 2cdbdabec6d05..d903b0c0021dc 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDataChannel+Private.h @@ -40,10 +40,10 @@ NS_ASSUME_NONNULL_BEGIN : (rtc::scoped_refptr)nativeDataChannel NS_DESIGNATED_INITIALIZER; + (webrtc::DataChannelInterface::DataState)nativeDataChannelStateForState: - (RTCDataChannelState)state; + (RTCDataChannelState)state; + (RTCDataChannelState)dataChannelStateForNativeState: - (webrtc::DataChannelInterface::DataState)nativeState; + (webrtc::DataChannelInterface::DataState)nativeState; + (NSString *)stringForState:(RTCDataChannelState)state; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h index 49a62164cd1a3..627d02a6c8c07 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCDtmfSender+Private.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN /** Initialize an RTCDtmfSender with a native DtmfSenderInterface. */ - (instancetype)initWithNativeDtmfSender: - (rtc::scoped_refptr)nativeDtmfSender NS_DESIGNATED_INITIALIZER; + (rtc::scoped_refptr)nativeDtmfSender NS_DESIGNATED_INITIALIZER; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h index 3e8fcc8075646..2c00e11721185 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCFieldTrials.h @@ -14,14 +14,14 @@ /** The only valid value for the following if set is kRTCFieldTrialEnabledValue. */ RTC_EXTERN NSString *const kRTCFieldTrialAudioForceABWENoTWCCKey; -RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03AdvertisedKey; -RTC_EXTERN NSString * const kRTCFieldTrialFlexFec03Key; -RTC_EXTERN NSString * const kRTCFieldTrialH264HighProfileKey; -RTC_EXTERN NSString * const kRTCFieldTrialMinimizeResamplingOnMobileKey; +RTC_EXTERN NSString *const kRTCFieldTrialFlexFec03AdvertisedKey; +RTC_EXTERN NSString *const kRTCFieldTrialFlexFec03Key; +RTC_EXTERN NSString *const kRTCFieldTrialH264HighProfileKey; +RTC_EXTERN NSString *const kRTCFieldTrialMinimizeResamplingOnMobileKey; RTC_EXTERN NSString *const kRTCFieldTrialUseNWPathMonitor; /** The valid value for field trials above. */ -RTC_EXTERN NSString * const kRTCFieldTrialEnabledValue; +RTC_EXTERN NSString *const kRTCFieldTrialEnabledValue; /** Initialize field trials using a dictionary mapping field trial keys to their * values. See above for valid keys and values. Must be called before any other diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h index ee51e27b2dca0..df45c79f44f35 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCMediaStreamTrack+Private.h @@ -46,10 +46,10 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)isEqualToTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track; + (webrtc::MediaStreamTrackInterface::TrackState)nativeTrackStateForState: - (RTCMediaStreamTrackState)state; + (RTCMediaStreamTrackState)state; + (RTCMediaStreamTrackState)trackStateForNativeState: - (webrtc::MediaStreamTrackInterface::TrackState)nativeState; + (webrtc::MediaStreamTrackInterface::TrackState)nativeState; + (NSString *)stringForState:(RTCMediaStreamTrackState)state; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h index 00f2ef783491f..9714f504ac017 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection+Private.h @@ -104,39 +104,39 @@ class PeerConnectionDelegateAdapter : public PeerConnectionObserver { NS_DESIGNATED_INITIALIZER; + (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: - (RTCSignalingState)state; + (RTCSignalingState)state; + (RTCSignalingState)signalingStateForNativeState: - (webrtc::PeerConnectionInterface::SignalingState)nativeState; + (webrtc::PeerConnectionInterface::SignalingState)nativeState; + (NSString *)stringForSignalingState:(RTCSignalingState)state; + (webrtc::PeerConnectionInterface::IceConnectionState)nativeIceConnectionStateForState: - (RTCIceConnectionState)state; + (RTCIceConnectionState)state; + (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState: - (RTCPeerConnectionState)state; + (RTCPeerConnectionState)state; + (RTCIceConnectionState)iceConnectionStateForNativeState: - (webrtc::PeerConnectionInterface::IceConnectionState)nativeState; + (webrtc::PeerConnectionInterface::IceConnectionState)nativeState; + (RTCPeerConnectionState)connectionStateForNativeState: - (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState; + (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState; + (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state; + (NSString *)stringForConnectionState:(RTCPeerConnectionState)state; + (webrtc::PeerConnectionInterface::IceGatheringState)nativeIceGatheringStateForState: - (RTCIceGatheringState)state; + (RTCIceGatheringState)state; + (RTCIceGatheringState)iceGatheringStateForNativeState: - (webrtc::PeerConnectionInterface::IceGatheringState)nativeState; + (webrtc::PeerConnectionInterface::IceGatheringState)nativeState; + (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state; + (webrtc::PeerConnectionInterface::StatsOutputLevel)nativeStatsOutputLevelForLevel: - (RTCStatsOutputLevel)level; + (RTCStatsOutputLevel)level; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h index 55af6868fd554..466e0534926d0 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnection.h @@ -82,9 +82,8 @@ typedef NS_ENUM(NSInteger, RTCStatsOutputLevel) { RTCStatsOutputLevelDebug, }; -typedef void (^RTCCreateSessionDescriptionCompletionHandler)(RTC_OBJC_TYPE(RTCSessionDescription) * - _Nullable sdp, - NSError *_Nullable error); +typedef void (^RTCCreateSessionDescriptionCompletionHandler)( + RTC_OBJC_TYPE(RTCSessionDescription) *_Nullable sdp, NSError *_Nullable error); typedef void (^RTCSetSessionDescriptionCompletionHandler)(NSError *_Nullable error); diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h index 9613646270858..822585ddc2b68 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory+Private.h @@ -29,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, readonly) rtc::Thread* signalingThread; @property(nonatomic, readonly) rtc::Thread* workerThread; +@property(nonatomic, readonly) rtc::Thread* networkThread; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm index c4d89e911d368..62b55543d455e 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -339,4 +339,8 @@ - (void)stopAecDump { return _workerThread.get(); } +- (rtc::Thread *)networkThread { + return _networkThread.get(); +} + @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h index 6aed0b4bc54bc..eccbcbc3a0768 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpReceiver+Private.h @@ -45,7 +45,7 @@ class RtpReceiverDelegateAdapter : public RtpReceiverObserverInterface { + (cricket::MediaType)nativeMediaTypeForMediaType:(RTCRtpMediaType)mediaType; -+ (NSString*)stringForMediaType:(RTCRtpMediaType)mediaType; ++ (NSString *)stringForMediaType:(RTCRtpMediaType)mediaType; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h index fcdf199869444..41bb083d2e42a 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpSender.h @@ -21,8 +21,8 @@ RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE (RTCRtpSender) -/** A unique identifier for this sender. */ -@property(nonatomic, readonly) NSString *senderId; + /** A unique identifier for this sender. */ + @property(nonatomic, readonly) NSString *senderId; /** The currently active RTCRtpParameters, as defined in * https://www.w3.org/TR/webrtc/#idl-def-RTCRtpParameters. diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h index 65d45fb88ecd9..868cbd80fe1df 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCRtpTransceiver+Private.h @@ -36,10 +36,10 @@ NS_ASSUME_NONNULL_BEGIN NS_DESIGNATED_INITIALIZER; + (webrtc::RtpTransceiverDirection)nativeRtpTransceiverDirectionFromDirection: - (RTCRtpTransceiverDirection)direction; + (RTCRtpTransceiverDirection)direction; + (RTCRtpTransceiverDirection)rtpTransceiverDirectionFromNativeDirection: - (webrtc::RtpTransceiverDirection)nativeDirection; + (webrtc::RtpTransceiverDirection)nativeDirection; @end diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h index aa087e557f307..d01c04b0b5135 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCSessionDescription+Private.h @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN * description. */ - (instancetype)initWithNativeDescription: - (const webrtc::SessionDescriptionInterface *)nativeDescription; + (const webrtc::SessionDescriptionInterface *)nativeDescription; + (std::string)stdStringForType:(RTCSdpType)type; diff --git a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h index 47c5241d516d0..e91302a207d13 100644 --- a/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h +++ b/third_party/libwebrtc/sdk/objc/api/peerconnection/RTCStatisticsReport+Private.h @@ -12,8 +12,9 @@ #include "api/stats/rtc_stats_report.h" -@interface RTC_OBJC_TYPE (RTCStatisticsReport) (Private) +@interface RTC_OBJC_TYPE (RTCStatisticsReport) +(Private) -- (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report; + - (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report; @end diff --git a/third_party/libwebrtc/sdk/objc/base/RTCLogging.h b/third_party/libwebrtc/sdk/objc/base/RTCLogging.h index 754945c8f2f06..0fa6a91b6982e 100644 --- a/third_party/libwebrtc/sdk/objc/base/RTCLogging.h +++ b/third_party/libwebrtc/sdk/objc/base/RTCLogging.h @@ -34,9 +34,12 @@ RTC_EXTERN NSString* RTCFileName(const char* filePath); // Some convenience macros. -#define RTCLogString(format, ...) \ - [NSString stringWithFormat:@"(%@:%d %s): " format, RTCFileName(__FILE__), \ - __LINE__, __FUNCTION__, ##__VA_ARGS__] +#define RTCLogString(format, ...) \ + [NSString stringWithFormat:@"(%@:%d %s): " format, \ + RTCFileName(__FILE__), \ + __LINE__, \ + __FUNCTION__, \ + ##__VA_ARGS__] #define RTCLogFormat(severity, format, ...) \ do { \ @@ -44,17 +47,13 @@ RTC_EXTERN NSString* RTCFileName(const char* filePath); RTCLogEx(severity, log_string); \ } while (false) -#define RTCLogVerbose(format, ...) \ - RTCLogFormat(RTCLoggingSeverityVerbose, format, ##__VA_ARGS__) +#define RTCLogVerbose(format, ...) RTCLogFormat(RTCLoggingSeverityVerbose, format, ##__VA_ARGS__) -#define RTCLogInfo(format, ...) \ - RTCLogFormat(RTCLoggingSeverityInfo, format, ##__VA_ARGS__) +#define RTCLogInfo(format, ...) RTCLogFormat(RTCLoggingSeverityInfo, format, ##__VA_ARGS__) -#define RTCLogWarning(format, ...) \ - RTCLogFormat(RTCLoggingSeverityWarning, format, ##__VA_ARGS__) +#define RTCLogWarning(format, ...) RTCLogFormat(RTCLoggingSeverityWarning, format, ##__VA_ARGS__) -#define RTCLogError(format, ...) \ - RTCLogFormat(RTCLoggingSeverityError, format, ##__VA_ARGS__) +#define RTCLogError(format, ...) RTCLogFormat(RTCLoggingSeverityError, format, ##__VA_ARGS__) #if !defined(NDEBUG) #define RTCLogDebug(format, ...) RTCLogInfo(format, ##__VA_ARGS__) diff --git a/third_party/libwebrtc/sdk/objc/base/RTCVideoEncoder.h b/third_party/libwebrtc/sdk/objc/base/RTCVideoEncoder.h index 2445d432d6397..27e6927ae230f 100644 --- a/third_party/libwebrtc/sdk/objc/base/RTCVideoEncoder.h +++ b/third_party/libwebrtc/sdk/objc/base/RTCVideoEncoder.h @@ -28,7 +28,7 @@ RTC_OBJC_EXPORT @protocol RTC_OBJC_TYPE (RTCVideoEncoder) -- (void)setCallback:(nullable RTCVideoEncoderCallback)callback; + - (void)setCallback : (nullable RTCVideoEncoderCallback)callback; - (NSInteger)startEncodeWithSettings:(RTC_OBJC_TYPE(RTCVideoEncoderSettings) *)settings numberOfCores:(int)numberOfCores; - (NSInteger)releaseEncoder; diff --git a/third_party/libwebrtc/sdk/objc/base/RTCVideoFrame.h b/third_party/libwebrtc/sdk/objc/base/RTCVideoFrame.h index f5638d27cf4b6..edf074b682d72 100644 --- a/third_party/libwebrtc/sdk/objc/base/RTCVideoFrame.h +++ b/third_party/libwebrtc/sdk/objc/base/RTCVideoFrame.h @@ -45,7 +45,7 @@ RTC_OBJC_EXPORT @property(nonatomic, readonly) id buffer; - (instancetype)init NS_UNAVAILABLE; -- (instancetype) new NS_UNAVAILABLE; +- (instancetype)new NS_UNAVAILABLE; /** Initialize an RTCVideoFrame from a pixel buffer, rotation, and timestamp. * Deprecated - initialize with a RTCCVPixelBuffer instead diff --git a/third_party/libwebrtc/sdk/objc/components/video_codec/helpers.h b/third_party/libwebrtc/sdk/objc/components/video_codec/helpers.h index 7c9ef1cd877b6..9dc05c8d59b3d 100644 --- a/third_party/libwebrtc/sdk/objc/components/video_codec/helpers.h +++ b/third_party/libwebrtc/sdk/objc/components/video_codec/helpers.h @@ -14,6 +14,7 @@ #include #include + #include // Convenience function for creating a dictionary. diff --git a/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.cc b/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.cc index b7330e1f9c20c..73c0ed0abd972 100644 --- a/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.cc +++ b/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.cc @@ -12,6 +12,7 @@ #include "sdk/objc/components/video_codec/nalu_rewriter.h" #include + #include #include diff --git a/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.h b/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.h index c6474971e2cf9..c2b9e4875ea52 100644 --- a/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.h +++ b/third_party/libwebrtc/sdk/objc/components/video_codec/nalu_rewriter.h @@ -12,12 +12,12 @@ #ifndef SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_NALU_REWRITER_H_ #define SDK_OBJC_FRAMEWORK_CLASSES_VIDEOTOOLBOX_NALU_REWRITER_H_ -#include "modules/video_coding/codecs/h264/include/h264.h" - #include + #include #include "common_video/h264/h264_common.h" +#include "modules/video_coding/codecs/h264/include/h264.h" #include "rtc_base/buffer.h" using webrtc::H264::NaluIndex; diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_capturer.h b/third_party/libwebrtc/sdk/objc/native/api/video_capturer.h index 9847d8148b99e..c1dfb07868b12 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_capturer.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_capturer.h @@ -11,8 +11,10 @@ #ifndef SDK_OBJC_NATIVE_API_VIDEO_CAPTURER_H_ #define SDK_OBJC_NATIVE_API_VIDEO_CAPTURER_H_ +// import #import "base/RTCVideoCapturer.h" +// include #include "api/media_stream_interface.h" #include "api/scoped_refptr.h" #include "rtc_base/thread.h" diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_decoder_factory.h b/third_party/libwebrtc/sdk/objc/native/api/video_decoder_factory.h index 03d8af3cfe658..9ba11d65a3801 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_decoder_factory.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_decoder_factory.h @@ -13,9 +13,8 @@ #include -#import "base/RTCVideoDecoderFactory.h" - #include "api/video_codecs/video_decoder_factory.h" +#import "base/RTCVideoDecoderFactory.h" namespace webrtc { diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_encoder_factory.h b/third_party/libwebrtc/sdk/objc/native/api/video_encoder_factory.h index 6e551b288d6db..ecd9ab090be99 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_encoder_factory.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_encoder_factory.h @@ -13,9 +13,8 @@ #include -#import "base/RTCVideoEncoderFactory.h" - #include "api/video_codecs/video_encoder_factory.h" +#import "base/RTCVideoEncoderFactory.h" namespace webrtc { diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_frame.h b/third_party/libwebrtc/sdk/objc/native/api/video_frame.h index b4416ffabe36a..4ca469f2f25a6 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_frame.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_frame.h @@ -11,9 +11,8 @@ #ifndef SDK_OBJC_NATIVE_API_VIDEO_FRAME_H_ #define SDK_OBJC_NATIVE_API_VIDEO_FRAME_H_ -#import "base/RTCVideoFrame.h" - #include "api/video/video_frame.h" +#import "base/RTCVideoFrame.h" namespace webrtc { diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_frame_buffer.h b/third_party/libwebrtc/sdk/objc/native/api/video_frame_buffer.h index 204d65d850fc9..68a8543d26f04 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_frame_buffer.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_frame_buffer.h @@ -11,8 +11,10 @@ #ifndef SDK_OBJC_NATIVE_API_VIDEO_FRAME_BUFFER_H_ #define SDK_OBJC_NATIVE_API_VIDEO_FRAME_BUFFER_H_ +// import #import "base/RTCVideoFrameBuffer.h" +// include #include "api/scoped_refptr.h" #include "common_video/include/video_frame_buffer.h" diff --git a/third_party/libwebrtc/sdk/objc/native/api/video_renderer.h b/third_party/libwebrtc/sdk/objc/native/api/video_renderer.h index 04796b80493bd..279857a8606b1 100644 --- a/third_party/libwebrtc/sdk/objc/native/api/video_renderer.h +++ b/third_party/libwebrtc/sdk/objc/native/api/video_renderer.h @@ -11,12 +11,11 @@ #ifndef SDK_OBJC_NATIVE_API_VIDEO_RENDERER_H_ #define SDK_OBJC_NATIVE_API_VIDEO_RENDERER_H_ -#import "base/RTCVideoRenderer.h" - #include #include "api/video/video_frame.h" #include "api/video/video_sink_interface.h" +#import "base/RTCVideoRenderer.h" namespace webrtc { diff --git a/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_module_ios.h b/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_module_ios.h index 9bcf114e32d01..189d7e6c9c8a7 100644 --- a/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_module_ios.h +++ b/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_module_ios.h @@ -13,9 +13,8 @@ #include -#include "audio_device_ios.h" - #include "api/task_queue/task_queue_factory.h" +#include "audio_device_ios.h" #include "modules/audio_device/audio_device_buffer.h" #include "modules/audio_device/include/audio_device.h" #include "rtc_base/checks.h" diff --git a/third_party/libwebrtc/sdk/objc/native/src/objc_video_decoder_factory.h b/third_party/libwebrtc/sdk/objc/native/src/objc_video_decoder_factory.h index 30ad8c2a4b21b..19c997e503e7a 100644 --- a/third_party/libwebrtc/sdk/objc/native/src/objc_video_decoder_factory.h +++ b/third_party/libwebrtc/sdk/objc/native/src/objc_video_decoder_factory.h @@ -29,8 +29,7 @@ class ObjCVideoDecoderFactory : public VideoDecoderFactory { id wrapped_decoder_factory() const; std::vector GetSupportedFormats() const override; - std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) override; + std::unique_ptr CreateVideoDecoder(const SdpVideoFormat& format) override; private: id decoder_factory_; diff --git a/third_party/libwebrtc/sdk/objc/native/src/objc_video_encoder_factory.h b/third_party/libwebrtc/sdk/objc/native/src/objc_video_encoder_factory.h index 38db5e6ae704d..85a1e5319d49e 100644 --- a/third_party/libwebrtc/sdk/objc/native/src/objc_video_encoder_factory.h +++ b/third_party/libwebrtc/sdk/objc/native/src/objc_video_encoder_factory.h @@ -31,8 +31,7 @@ class ObjCVideoEncoderFactory : public VideoEncoderFactory { std::vector GetSupportedFormats() const override; std::vector GetImplementations() const override; - std::unique_ptr CreateVideoEncoder( - const SdpVideoFormat& format) override; + std::unique_ptr CreateVideoEncoder(const SdpVideoFormat& format) override; std::unique_ptr GetEncoderSelector() const override; private: diff --git a/third_party/libwebrtc/sdk/objc/native/src/objc_video_frame.h b/third_party/libwebrtc/sdk/objc/native/src/objc_video_frame.h index c2931cb2f8331..0781d47ee6c8b 100644 --- a/third_party/libwebrtc/sdk/objc/native/src/objc_video_frame.h +++ b/third_party/libwebrtc/sdk/objc/native/src/objc_video_frame.h @@ -11,9 +11,8 @@ #ifndef SDK_OBJC_NATIVE_SRC_OBJC_VIDEO_FRAME_H_ #define SDK_OBJC_NATIVE_SRC_OBJC_VIDEO_FRAME_H_ -#import "base/RTCVideoFrame.h" - #include "api/video/video_frame.h" +#import "base/RTCVideoFrame.h" namespace webrtc { diff --git a/third_party/libwebrtc/test/BUILD.gn b/third_party/libwebrtc/test/BUILD.gn index 6fd790332b993..55153909d3b12 100644 --- a/third_party/libwebrtc/test/BUILD.gn +++ b/third_party/libwebrtc/test/BUILD.gn @@ -22,6 +22,7 @@ if (!build_with_chromium) { ":test_common", ":test_renderer", ":test_support", + ":test_video_capturer", ":video_test_common", ] @@ -110,6 +111,72 @@ rtc_library("frame_utils") { ] } +rtc_library("test_video_capturer") { + testonly = true + sources = [ + "test_video_capturer.cc", + "test_video_capturer.h", + ] + deps = [ + "../api:scoped_refptr", + "../api/video:video_frame", + "../api/video:video_rtp_headers", + "../media:rtc_media_base", + "../rtc_base/synchronization:mutex", + ] +} + +rtc_library("create_frame_generator_capturer") { + visibility = [ "*" ] + testonly = true + sources = [ + "create_frame_generator_capturer.cc", + "create_frame_generator_capturer.h", + ] + deps = [ + ":fileutils", + ":frame_generator_capturer", + "../api:create_frame_generator", + "../api:frame_generator_api", + "../api/task_queue", + "../api/units:time_delta", + "../rtc_base:checks", + "../system_wrappers", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("frame_generator_capturer") { + visibility = [ "*" ] + testonly = true + sources = [ + "frame_generator_capturer.cc", + "frame_generator_capturer.h", + ] + deps = [ + ":test_video_capturer", + "../api:frame_generator_api", + "../api/task_queue", + "../api/units:time_delta", + "../api/video:video_frame", + "../api/video:video_rtp_headers", + "../rtc_base:checks", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:rtc_task_queue", + "../rtc_base/synchronization:mutex", + "../rtc_base/task_utils:repeating_task", + "../system_wrappers", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + rtc_library("video_test_common") { visibility = [ "*" ] testonly = true @@ -119,12 +186,8 @@ rtc_library("video_test_common") { "fake_videorenderer.h", "frame_forwarder.cc", "frame_forwarder.h", - "frame_generator_capturer.cc", - "frame_generator_capturer.h", "mappable_native_buffer.cc", "mappable_native_buffer.h", - "test_video_capturer.cc", - "test_video_capturer.h", "video_codec_settings.h", "video_decoder_proxy_factory.h", "video_encoder_nullable_proxy_factory.h", @@ -132,9 +195,11 @@ rtc_library("video_test_common") { ] deps = [ + ":create_frame_generator_capturer", ":fileutils", ":frame_utils", ":scoped_key_value_config", + ":test_video_capturer", "../api:array_view", "../api:create_frame_generator", "../api:frame_generator_api", @@ -185,6 +250,7 @@ if (!build_with_chromium) { "mac_capturer.mm", ] deps = [ + ":test_video_capturer", ":video_test_common", "../api:libjingle_peerconnection_api", "../api:media_stream_interface", @@ -205,7 +271,10 @@ if (!build_with_chromium) { "platform_video_capturer.cc", "platform_video_capturer.h", ] - deps = [ ":video_test_common" ] + deps = [ + ":test_video_capturer", + ":video_test_common", + ] absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] if (is_mac || is_ios) { deps += [ ":video_test_mac" ] @@ -644,11 +713,13 @@ if (rtc_include_tests) { deps = [ ":call_config_utils", ":copy_to_file_audio_capturer_unittest", + ":create_frame_generator_capturer", ":direct_transport", ":fake_video_codecs", ":fileutils", ":fileutils_unittests", ":fixed_fps_video_frame_writer_adapter_test", + ":frame_generator_capturer", ":frame_generator_impl", ":perf_test", ":rtc_expect_death", @@ -1001,6 +1072,12 @@ rtc_library("run_loop") { absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ] } +rtc_library("video_test_constants") { + testonly = true + sources = [ "video_test_constants.h" ] + deps = [ "../api/units:time_delta" ] +} + rtc_library("test_common") { testonly = true sources = [ @@ -1018,11 +1095,13 @@ rtc_library("test_common") { ":encoder_settings", ":fake_video_codecs", ":fileutils", + ":frame_generator_capturer", ":mock_transport", ":run_loop", ":scoped_key_value_config", ":test_support", ":video_test_common", + ":video_test_constants", "../api:array_view", "../api:create_frame_generator", "../api:frame_generator_api", @@ -1048,7 +1127,8 @@ rtc_library("test_common") { "../call:simulated_network", "../call:simulated_packet_receiver", "../call:video_stream_api", - "../modules/audio_device:audio_device_impl", + "../modules/audio_device:audio_device_api", + "../modules/audio_device:test_audio_device_module", "../modules/audio_mixer:audio_mixer_impl", "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", @@ -1222,7 +1302,7 @@ rtc_library("copy_to_file_audio_capturer") { deps = [ "../api:array_view", "../common_audio", - "../modules/audio_device:audio_device_impl", + "../modules/audio_device:test_audio_device_module", "../rtc_base:buffer", ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] @@ -1235,7 +1315,7 @@ rtc_library("copy_to_file_audio_capturer_unittest") { ":copy_to_file_audio_capturer", ":fileutils", ":test_support", - "../modules/audio_device:audio_device_impl", + "../modules/audio_device:test_audio_device_module", ] } diff --git a/third_party/libwebrtc/test/call_test.cc b/third_party/libwebrtc/test/call_test.cc index 5fc7feb3c03a7..7a1bbd2969949 100644 --- a/third_party/libwebrtc/test/call_test.cc +++ b/third_party/libwebrtc/test/call_test.cc @@ -22,6 +22,8 @@ #include "call/fake_network_pipe.h" #include "call/packet_receiver.h" #include "call/simulated_network.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_device/include/test_audio_device.h" #include "modules/audio_mixer/audio_mixer_impl.h" #include "rtc_base/checks.h" #include "rtc_base/event.h" @@ -29,6 +31,7 @@ #include "test/fake_encoder.h" #include "test/rtp_rtcp_observer.h" #include "test/testsupport/file_utils.h" +#include "test/video_test_constants.h" #include "video/config/video_encoder_config.h" namespace webrtc { @@ -174,9 +177,9 @@ void CallTest::RunBaseTest(BaseTest* test) { } if (num_video_streams_ > 0) { - int width = kDefaultWidth; - int height = kDefaultHeight; - int frame_rate = kDefaultFramerate; + int width = VideoTestConstants::kDefaultWidth; + int height = VideoTestConstants::kDefaultHeight; + int frame_rate = VideoTestConstants::kDefaultFramerate; test->ModifyVideoCaptureStartResolution(&width, &height, &frame_rate); test->ModifyVideoDegradationPreference(°radation_preference_); CreateFrameGeneratorCapturer(frame_rate, width, height); @@ -246,13 +249,15 @@ void CallTest::CreateVideoSendConfig(VideoSendStream::Config* video_config, size_t num_video_streams, size_t num_used_ssrcs, Transport* send_transport) { - RTC_DCHECK_LE(num_video_streams + num_used_ssrcs, kNumSsrcs); + RTC_DCHECK_LE(num_video_streams + num_used_ssrcs, + VideoTestConstants::kNumSsrcs); *video_config = VideoSendStream::Config(send_transport); video_config->encoder_settings.encoder_factory = &fake_encoder_factory_; video_config->encoder_settings.bitrate_allocator_factory = bitrate_allocator_factory_.get(); video_config->rtp.payload_name = "FAKE"; - video_config->rtp.payload_type = kFakeVideoSendPayloadType; + video_config->rtp.payload_type = + VideoTestConstants::kFakeVideoSendPayloadType; video_config->rtp.extmap_allow_mixed = true; AddRtpExtensionByUri(RtpExtension::kTransportSequenceNumberUri, &video_config->rtp.extensions); @@ -272,7 +277,8 @@ void CallTest::CreateVideoSendConfig(VideoSendStream::Config* video_config, &video_encoder_configs_.back()); } for (size_t i = 0; i < num_video_streams; ++i) - video_config->rtp.ssrcs.push_back(kVideoSendSsrcs[num_used_ssrcs + i]); + video_config->rtp.ssrcs.push_back( + VideoTestConstants::kVideoSendSsrcs[num_used_ssrcs + i]); AddRtpExtensionByUri(RtpExtension::kVideoRotationUri, &video_config->rtp.extensions); AddRtpExtensionByUri(RtpExtension::kColorSpaceUri, @@ -286,12 +292,13 @@ void CallTest::CreateAudioAndFecSendConfigs(size_t num_audio_streams, RTC_DCHECK_LE(num_flexfec_streams, 1); if (num_audio_streams > 0) { AudioSendStream::Config audio_send_config(send_transport); - audio_send_config.rtp.ssrc = kAudioSendSsrc; + audio_send_config.rtp.ssrc = VideoTestConstants::kAudioSendSsrc; AddRtpExtensionByUri(RtpExtension::kTransportSequenceNumberUri, &audio_send_config.rtp.extensions); audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec( - kAudioSendPayloadType, {"opus", 48000, 2, {{"stereo", "1"}}}); + VideoTestConstants::kAudioSendPayloadType, + {"opus", 48000, 2, {{"stereo", "1"}}}); audio_send_config.min_bitrate_bps = 6000; audio_send_config.max_bitrate_bps = 60000; audio_send_config.encoder_factory = audio_encoder_factory_; @@ -300,7 +307,7 @@ void CallTest::CreateAudioAndFecSendConfigs(size_t num_audio_streams, // TODO(brandtr): Update this when we support multistream protection. if (num_flexfec_streams > 0) { - SetSendFecConfig({kVideoSendSsrcs[0]}); + SetSendFecConfig({VideoTestConstants::kVideoSendSsrcs[0]}); } } @@ -309,23 +316,29 @@ void CallTest::SetAudioConfig(const AudioSendStream::Config& config) { } void CallTest::SetSendFecConfig(std::vector video_send_ssrcs) { - GetVideoSendConfig()->rtp.flexfec.payload_type = kFlexfecPayloadType; - GetVideoSendConfig()->rtp.flexfec.ssrc = kFlexfecSendSsrc; + GetVideoSendConfig()->rtp.flexfec.payload_type = + VideoTestConstants::kFlexfecPayloadType; + GetVideoSendConfig()->rtp.flexfec.ssrc = VideoTestConstants::kFlexfecSendSsrc; GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs = video_send_ssrcs; } void CallTest::SetSendUlpFecConfig(VideoSendStream::Config* send_config) { - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; - send_config->rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType; + send_config->rtp.ulpfec.red_payload_type = + VideoTestConstants::kRedPayloadType; + send_config->rtp.ulpfec.ulpfec_payload_type = + VideoTestConstants::kUlpfecPayloadType; + send_config->rtp.ulpfec.red_rtx_payload_type = + VideoTestConstants::kRtxRedPayloadType; } void CallTest::SetReceiveUlpFecConfig( VideoReceiveStreamInterface::Config* receive_config) { - receive_config->rtp.red_payload_type = kRedPayloadType; - receive_config->rtp.ulpfec_payload_type = kUlpfecPayloadType; - receive_config->rtp.rtx_associated_payload_types[kRtxRedPayloadType] = - kRedPayloadType; + receive_config->rtp.red_payload_type = VideoTestConstants::kRedPayloadType; + receive_config->rtp.ulpfec_payload_type = + VideoTestConstants::kUlpfecPayloadType; + receive_config->rtp + .rtx_associated_payload_types[VideoTestConstants::kRtxRedPayloadType] = + VideoTestConstants::kRedPayloadType; } void CallTest::CreateSendConfig(size_t num_video_streams, @@ -373,7 +386,7 @@ void CallTest::AddMatchingVideoReceiveConfigs( int rtp_history_ms) { RTC_DCHECK(!video_send_config.rtp.ssrcs.empty()); VideoReceiveStreamInterface::Config default_config(rtcp_send_transport); - default_config.rtp.local_ssrc = kReceiverLocalVideoSsrc; + default_config.rtp.local_ssrc = VideoTestConstants::kReceiverLocalVideoSsrc; default_config.rtp.nack.rtp_history_ms = rtp_history_ms; // Enable RTT calculation so NTP time estimator will work. default_config.rtp.rtcp_xr.receiver_reference_time_report = @@ -386,7 +399,8 @@ void CallTest::AddMatchingVideoReceiveConfigs( video_recv_config.decoders.clear(); if (!video_send_config.rtp.rtx.ssrcs.empty()) { video_recv_config.rtp.rtx_ssrc = video_send_config.rtp.rtx.ssrcs[i]; - video_recv_config.rtp.rtx_associated_payload_types[kSendRtxPayloadType] = + video_recv_config.rtp.rtx_associated_payload_types + [VideoTestConstants::kSendRtxPayloadType] = video_send_config.rtp.payload_type; } video_recv_config.rtp.remote_ssrc = video_send_config.rtp.ssrcs[i]; @@ -431,11 +445,12 @@ AudioReceiveStreamInterface::Config CallTest::CreateMatchingAudioConfig( Transport* transport, std::string sync_group) { AudioReceiveStreamInterface::Config audio_config; - audio_config.rtp.local_ssrc = kReceiverLocalAudioSsrc; + audio_config.rtp.local_ssrc = VideoTestConstants::kReceiverLocalAudioSsrc; audio_config.rtcp_send_transport = transport; audio_config.rtp.remote_ssrc = send_config.rtp.ssrc; audio_config.decoder_factory = audio_decoder_factory; - audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}}; + audio_config.decoder_map = { + {VideoTestConstants::kAudioSendPayloadType, {"opus", 48000, 2}}}; audio_config.sync_group = sync_group; return audio_config; } @@ -447,7 +462,7 @@ void CallTest::CreateMatchingFecConfig( config.payload_type = send_config.rtp.flexfec.payload_type; config.rtp.remote_ssrc = send_config.rtp.flexfec.ssrc; config.protected_media_ssrcs = send_config.rtp.flexfec.protected_media_ssrcs; - config.rtp.local_ssrc = kReceiverLocalVideoSsrc; + config.rtp.local_ssrc = VideoTestConstants::kReceiverLocalVideoSsrc; if (!video_receive_configs_.empty()) { video_receive_configs_[0].rtp.protected_by_flexfec = true; video_receive_configs_[0].rtp.packet_sink_ = this; @@ -728,33 +743,19 @@ void CallTest::AddRtpExtensionByUri( } } -constexpr size_t CallTest::kNumSsrcs; -const int CallTest::kDefaultWidth; -const int CallTest::kDefaultHeight; -const int CallTest::kDefaultFramerate; -const uint32_t CallTest::kSendRtxSsrcs[kNumSsrcs] = { - 0xBADCAFD, 0xBADCAFE, 0xBADCAFF, 0xBADCB00, 0xBADCB01, 0xBADCB02}; -const uint32_t CallTest::kVideoSendSsrcs[kNumSsrcs] = { - 0xC0FFED, 0xC0FFEE, 0xC0FFEF, 0xC0FFF0, 0xC0FFF1, 0xC0FFF2}; -const uint32_t CallTest::kAudioSendSsrc = 0xDEADBEEF; -const uint32_t CallTest::kFlexfecSendSsrc = 0xBADBEEF; -const uint32_t CallTest::kReceiverLocalVideoSsrc = 0x123456; -const uint32_t CallTest::kReceiverLocalAudioSsrc = 0x1234567; -const int CallTest::kNackRtpHistoryMs = 1000; - const std::map CallTest::payload_type_map_ = { - {CallTest::kVideoSendPayloadType, MediaType::VIDEO}, - {CallTest::kFakeVideoSendPayloadType, MediaType::VIDEO}, - {CallTest::kSendRtxPayloadType, MediaType::VIDEO}, - {CallTest::kPayloadTypeVP8, MediaType::VIDEO}, - {CallTest::kPayloadTypeVP9, MediaType::VIDEO}, - {CallTest::kPayloadTypeH264, MediaType::VIDEO}, - {CallTest::kPayloadTypeGeneric, MediaType::VIDEO}, - {CallTest::kRedPayloadType, MediaType::VIDEO}, - {CallTest::kRtxRedPayloadType, MediaType::VIDEO}, - {CallTest::kUlpfecPayloadType, MediaType::VIDEO}, - {CallTest::kFlexfecPayloadType, MediaType::VIDEO}, - {CallTest::kAudioSendPayloadType, MediaType::AUDIO}}; + {VideoTestConstants::kVideoSendPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kFakeVideoSendPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kSendRtxPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kPayloadTypeVP8, MediaType::VIDEO}, + {VideoTestConstants::kPayloadTypeVP9, MediaType::VIDEO}, + {VideoTestConstants::kPayloadTypeH264, MediaType::VIDEO}, + {VideoTestConstants::kPayloadTypeGeneric, MediaType::VIDEO}, + {VideoTestConstants::kRedPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kRtxRedPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kUlpfecPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kFlexfecPayloadType, MediaType::VIDEO}, + {VideoTestConstants::kAudioSendPayloadType, MediaType::AUDIO}}; BaseTest::BaseTest() {} @@ -770,9 +771,9 @@ std::unique_ptr BaseTest::CreateRenderer() { return TestAudioDeviceModule::CreateDiscardRenderer(48000); } -void BaseTest::OnFakeAudioDevicesCreated( - TestAudioDeviceModule* send_audio_device, - TestAudioDeviceModule* recv_audio_device) {} +void BaseTest::OnFakeAudioDevicesCreated(AudioDeviceModule* send_audio_device, + AudioDeviceModule* recv_audio_device) { +} void BaseTest::ModifySenderBitrateConfig(BitrateConstraints* bitrate_config) {} diff --git a/third_party/libwebrtc/test/call_test.h b/third_party/libwebrtc/test/call_test.h index 3324bc4b5e101..d01bac4204f49 100644 --- a/third_party/libwebrtc/test/call_test.h +++ b/third_party/libwebrtc/test/call_test.h @@ -26,6 +26,7 @@ #include "api/units/time_delta.h" #include "api/video/video_bitrate_allocator_factory.h" #include "call/call.h" +#include "modules/audio_device/include/audio_device.h" #include "modules/audio_device/include/test_audio_device.h" #include "test/encoder_settings.h" #include "test/fake_decoder.h" @@ -35,6 +36,7 @@ #include "test/rtp_rtcp_observer.h" #include "test/run_loop.h" #include "test/scoped_key_value_config.h" +#include "test/video_test_constants.h" namespace webrtc { namespace test { @@ -46,34 +48,6 @@ class CallTest : public ::testing::Test, public RtpPacketSinkInterface { CallTest(); virtual ~CallTest(); - static constexpr size_t kNumSsrcs = 6; - static const int kNumSimulcastStreams = 3; - static const int kDefaultWidth = 320; - static const int kDefaultHeight = 180; - static const int kDefaultFramerate = 30; - static constexpr TimeDelta kDefaultTimeout = TimeDelta::Seconds(30); - static constexpr TimeDelta kLongTimeout = TimeDelta::Seconds(120); - enum classPayloadTypes : uint8_t { - kSendRtxPayloadType = 98, - kRtxRedPayloadType = 99, - kVideoSendPayloadType = 100, - kAudioSendPayloadType = 103, - kRedPayloadType = 118, - kUlpfecPayloadType = 119, - kFlexfecPayloadType = 120, - kPayloadTypeH264 = 122, - kPayloadTypeVP8 = 123, - kPayloadTypeVP9 = 124, - kPayloadTypeGeneric = 125, - kFakeVideoSendPayloadType = 126, - }; - static const uint32_t kSendRtxSsrcs[kNumSsrcs]; - static const uint32_t kVideoSendSsrcs[kNumSsrcs]; - static const uint32_t kAudioSendSsrc; - static const uint32_t kFlexfecSendSsrc; - static const uint32_t kReceiverLocalVideoSsrc; - static const uint32_t kReceiverLocalAudioSsrc; - static const int kNackRtpHistoryMs; static const std::map payload_type_map_; protected: @@ -271,8 +245,8 @@ class CallTest : public ::testing::Test, public RtpPacketSinkInterface { std::vector rtp_extensions_; rtc::scoped_refptr apm_send_; rtc::scoped_refptr apm_recv_; - rtc::scoped_refptr fake_send_audio_device_; - rtc::scoped_refptr fake_recv_audio_device_; + rtc::scoped_refptr fake_send_audio_device_; + rtc::scoped_refptr fake_recv_audio_device_; }; class BaseTest : public RtpRtcpObserver { @@ -290,9 +264,8 @@ class BaseTest : public RtpRtcpObserver { virtual std::unique_ptr CreateCapturer(); virtual std::unique_ptr CreateRenderer(); - virtual void OnFakeAudioDevicesCreated( - TestAudioDeviceModule* send_audio_device, - TestAudioDeviceModule* recv_audio_device); + virtual void OnFakeAudioDevicesCreated(AudioDeviceModule* send_audio_device, + AudioDeviceModule* recv_audio_device); virtual void ModifySenderBitrateConfig(BitrateConstraints* bitrate_config); virtual void ModifyReceiverBitrateConfig(BitrateConstraints* bitrate_config); diff --git a/third_party/libwebrtc/test/create_frame_generator_capturer.cc b/third_party/libwebrtc/test/create_frame_generator_capturer.cc new file mode 100644 index 0000000000000..a4088d90e5e96 --- /dev/null +++ b/third_party/libwebrtc/test/create_frame_generator_capturer.cc @@ -0,0 +1,133 @@ +/* + * Copyright (c) 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 "test/create_frame_generator_capturer.h" + +#include +#include +#include +#include + +#include "absl/strings/match.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/test/create_frame_generator.h" +#include "api/test/frame_generator_interface.h" +#include "api/units/time_delta.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/clock.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { +namespace test { +namespace { + +std::string TransformFilePath(std::string path) { + static const std::string resource_prefix = "res://"; + int ext_pos = path.rfind('.'); + if (ext_pos < 0) { + return test::ResourcePath(path, "yuv"); + } else if (absl::StartsWith(path, resource_prefix)) { + std::string name = path.substr(resource_prefix.length(), ext_pos); + std::string ext = path.substr(ext_pos, path.size()); + return test::ResourcePath(name, ext); + } + return path; +} + +} // namespace + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquaresVideo config) { + return std::make_unique( + clock, + CreateSquareFrameGenerator(config.width, config.height, + config.pixel_format, config.num_squares), + config.framerate, task_queue_factory); +} +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquareSlides config) { + return std::make_unique( + clock, + CreateSlideFrameGenerator( + config.width, config.height, + /*frame_repeat_count*/ config.change_interval.seconds() * + config.framerate), + config.framerate, task_queue_factory); +} +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::VideoFile config) { + RTC_CHECK(config.width && config.height); + return std::make_unique( + clock, + CreateFromYuvFileFrameGenerator({TransformFilePath(config.name)}, + config.width, config.height, + /*frame_repeat_count*/ 1), + config.framerate, task_queue_factory); +} + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::ImageSlides config) { + std::unique_ptr slides_generator; + std::vector paths = config.paths; + for (std::string& path : paths) + path = TransformFilePath(path); + + if (config.crop.width || config.crop.height) { + TimeDelta pause_duration = + config.change_interval - config.crop.scroll_duration; + RTC_CHECK_GE(pause_duration, TimeDelta::Zero()); + int crop_width = config.crop.width.value_or(config.width); + int crop_height = config.crop.height.value_or(config.height); + RTC_CHECK_LE(crop_width, config.width); + RTC_CHECK_LE(crop_height, config.height); + slides_generator = CreateScrollingInputFromYuvFilesFrameGenerator( + clock, paths, config.width, config.height, crop_width, crop_height, + config.crop.scroll_duration.ms(), pause_duration.ms()); + } else { + slides_generator = CreateFromYuvFileFrameGenerator( + paths, config.width, config.height, + /*frame_repeat_count*/ config.change_interval.seconds() * + config.framerate); + } + return std::make_unique( + clock, std::move(slides_generator), config.framerate, task_queue_factory); +} + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + const FrameGeneratorCapturerConfig& config) { + if (config.video_file) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.video_file); + } else if (config.image_slides) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.image_slides); + } else if (config.squares_slides) { + return CreateFrameGeneratorCapturer(clock, task_queue_factory, + *config.squares_slides); + } else { + return CreateFrameGeneratorCapturer( + clock, task_queue_factory, + config.squares_video.value_or( + FrameGeneratorCapturerConfig::SquaresVideo())); + } +} + +} // namespace test +} // namespace webrtc diff --git a/third_party/libwebrtc/test/create_frame_generator_capturer.h b/third_party/libwebrtc/test/create_frame_generator_capturer.h new file mode 100644 index 0000000000000..0d8ec71df3d53 --- /dev/null +++ b/third_party/libwebrtc/test/create_frame_generator_capturer.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 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 TEST_CREATE_FRAME_GENERATOR_CAPTURER_H_ +#define TEST_CREATE_FRAME_GENERATOR_CAPTURER_H_ + +#include +#include +#include + +#include "absl/types/optional.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/test/frame_generator_interface.h" +#include "api/units/time_delta.h" +#include "system_wrappers/include/clock.h" +#include "test/frame_generator_capturer.h" + +namespace webrtc { +namespace test { + +namespace frame_gen_cap_impl { +template +class AutoOpt : public absl::optional { + public: + using absl::optional::optional; + T* operator->() { + if (!absl::optional::has_value()) + this->emplace(T()); + return absl::optional::operator->(); + } +}; +} // namespace frame_gen_cap_impl + +struct FrameGeneratorCapturerConfig { + struct SquaresVideo { + int framerate = 30; + FrameGeneratorInterface::OutputType pixel_format = + FrameGeneratorInterface::OutputType::kI420; + int width = 320; + int height = 180; + int num_squares = 10; + }; + + struct SquareSlides { + int framerate = 30; + TimeDelta change_interval = TimeDelta::Seconds(10); + int width = 1600; + int height = 1200; + }; + + struct VideoFile { + int framerate = 30; + std::string name; + // Must be set to width and height of the source video file. + int width = 0; + int height = 0; + }; + + struct ImageSlides { + int framerate = 30; + TimeDelta change_interval = TimeDelta::Seconds(10); + struct Crop { + TimeDelta scroll_duration = TimeDelta::Seconds(0); + absl::optional width; + absl::optional height; + } crop; + int width = 1850; + int height = 1110; + std::vector paths = { + "web_screenshot_1850_1110", + "presentation_1850_1110", + "photo_1850_1110", + "difficult_photo_1850_1110", + }; + }; + + frame_gen_cap_impl::AutoOpt squares_video; + frame_gen_cap_impl::AutoOpt squares_slides; + frame_gen_cap_impl::AutoOpt video_file; + frame_gen_cap_impl::AutoOpt image_slides; +}; + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquaresVideo config); + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::SquareSlides config); + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::VideoFile config); + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + FrameGeneratorCapturerConfig::ImageSlides config); + +std::unique_ptr CreateFrameGeneratorCapturer( + Clock* clock, + TaskQueueFactory& task_queue_factory, + const FrameGeneratorCapturerConfig& config); + +} // namespace test +} // namespace webrtc + +#endif // TEST_CREATE_FRAME_GENERATOR_CAPTURER_H_ diff --git a/third_party/libwebrtc/test/frame_generator_capturer.cc b/third_party/libwebrtc/test/frame_generator_capturer.cc index c69fca0965f33..6ba0807a74e7a 100644 --- a/third_party/libwebrtc/test/frame_generator_capturer.cc +++ b/third_party/libwebrtc/test/frame_generator_capturer.cc @@ -12,36 +12,30 @@ #include #include -#include +#include #include #include -#include -#include "absl/strings/match.h" -#include "api/test/create_frame_generator.h" +#include "absl/types/optional.h" +#include "api/task_queue/task_queue_base.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/test/frame_generator_interface.h" +#include "api/units/time_delta.h" +#include "api/video/color_space.h" +#include "api/video/video_frame.h" +#include "api/video/video_rotation.h" +#include "api/video/video_sink_interface.h" +#include "api/video/video_source_interface.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "rtc_base/synchronization/mutex.h" #include "rtc_base/task_queue.h" -#include "rtc_base/time_utils.h" +#include "rtc_base/task_utils/repeating_task.h" #include "system_wrappers/include/clock.h" -#include "test/testsupport/file_utils.h" +#include "test/test_video_capturer.h" namespace webrtc { namespace test { -namespace { -std::string TransformFilePath(std::string path) { - static const std::string resource_prefix = "res://"; - int ext_pos = path.rfind('.'); - if (ext_pos < 0) { - return test::ResourcePath(path, "yuv"); - } else if (absl::StartsWith(path, resource_prefix)) { - std::string name = path.substr(resource_prefix.length(), ext_pos); - std::string ext = path.substr(ext_pos, path.size()); - return test::ResourcePath(name, ext); - } - return path; -} -} // namespace FrameGeneratorCapturer::FrameGeneratorCapturer( Clock* clock, @@ -66,88 +60,6 @@ FrameGeneratorCapturer::~FrameGeneratorCapturer() { Stop(); } -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquaresVideo config) { - return std::make_unique( - clock, - CreateSquareFrameGenerator(config.width, config.height, - config.pixel_format, config.num_squares), - config.framerate, task_queue_factory); -} -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquareSlides config) { - return std::make_unique( - clock, - CreateSlideFrameGenerator( - config.width, config.height, - /*frame_repeat_count*/ config.change_interval.seconds() * - config.framerate), - config.framerate, task_queue_factory); -} -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::VideoFile config) { - RTC_CHECK(config.width && config.height); - return std::make_unique( - clock, - CreateFromYuvFileFrameGenerator({TransformFilePath(config.name)}, - config.width, config.height, - /*frame_repeat_count*/ 1), - config.framerate, task_queue_factory); -} - -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::ImageSlides config) { - std::unique_ptr slides_generator; - std::vector paths = config.paths; - for (std::string& path : paths) - path = TransformFilePath(path); - - if (config.crop.width || config.crop.height) { - TimeDelta pause_duration = - config.change_interval - config.crop.scroll_duration; - RTC_CHECK_GE(pause_duration, TimeDelta::Zero()); - int crop_width = config.crop.width.value_or(config.width); - int crop_height = config.crop.height.value_or(config.height); - RTC_CHECK_LE(crop_width, config.width); - RTC_CHECK_LE(crop_height, config.height); - slides_generator = CreateScrollingInputFromYuvFilesFrameGenerator( - clock, paths, config.width, config.height, crop_width, crop_height, - config.crop.scroll_duration.ms(), pause_duration.ms()); - } else { - slides_generator = CreateFromYuvFileFrameGenerator( - paths, config.width, config.height, - /*frame_repeat_count*/ config.change_interval.seconds() * - config.framerate); - } - return std::make_unique( - clock, std::move(slides_generator), config.framerate, task_queue_factory); -} - -std::unique_ptr FrameGeneratorCapturer::Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - const FrameGeneratorCapturerConfig& config) { - if (config.video_file) { - return Create(clock, task_queue_factory, *config.video_file); - } else if (config.image_slides) { - return Create(clock, task_queue_factory, *config.image_slides); - } else if (config.squares_slides) { - return Create(clock, task_queue_factory, *config.squares_slides); - } else { - return Create(clock, task_queue_factory, - config.squares_video.value_or( - FrameGeneratorCapturerConfig::SquaresVideo())); - } -} - void FrameGeneratorCapturer::SetFakeRotation(VideoRotation rotation) { MutexLock lock(&lock_); fake_rotation_ = rotation; @@ -177,49 +89,39 @@ bool FrameGeneratorCapturer::Init() { } void FrameGeneratorCapturer::InsertFrame() { - absl::optional resolution; - - { - MutexLock lock(&lock_); - if (sending_) { - FrameGeneratorInterface::VideoFrameData frame_data = - frame_generator_->NextFrame(); - // TODO(srte): Use more advanced frame rate control to allow arbritrary - // fractions. - int decimation = - std::round(static_cast(source_fps_) / target_capture_fps_); - for (int i = 1; i < decimation; ++i) - frame_data = frame_generator_->NextFrame(); - - VideoFrame frame = - VideoFrame::Builder() - .set_video_frame_buffer(frame_data.buffer) - .set_rotation(fake_rotation_) - .set_timestamp_us(clock_->TimeInMicroseconds()) - .set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()) - .set_update_rect(frame_data.update_rect) - .set_color_space(fake_color_space_) - .build(); - if (first_frame_capture_time_ == -1) { - first_frame_capture_time_ = frame.ntp_time_ms(); - } - - resolution = Resolution{frame.width(), frame.height()}; - - TestVideoCapturer::OnFrame(frame); + MutexLock lock(&lock_); + if (sending_) { + FrameGeneratorInterface::VideoFrameData frame_data = + frame_generator_->NextFrame(); + // TODO(srte): Use more advanced frame rate control to allow arbritrary + // fractions. + int decimation = + std::round(static_cast(source_fps_) / target_capture_fps_); + for (int i = 1; i < decimation; ++i) + frame_data = frame_generator_->NextFrame(); + + VideoFrame frame = VideoFrame::Builder() + .set_video_frame_buffer(frame_data.buffer) + .set_rotation(fake_rotation_) + .set_timestamp_us(clock_->TimeInMicroseconds()) + .set_ntp_time_ms(clock_->CurrentNtpInMilliseconds()) + .set_update_rect(frame_data.update_rect) + .set_color_space(fake_color_space_) + .build(); + if (first_frame_capture_time_ == -1) { + first_frame_capture_time_ = frame.ntp_time_ms(); } - } - if (resolution) { - MutexLock lock(&stats_lock_); - source_resolution_ = resolution; + TestVideoCapturer::OnFrame(frame); } } absl::optional -FrameGeneratorCapturer::GetResolution() { - MutexLock lock(&stats_lock_); - return source_resolution_; +FrameGeneratorCapturer::GetResolution() const { + FrameGeneratorInterface::Resolution resolution = + frame_generator_->GetResolution(); + return Resolution{.width = static_cast(resolution.width), + .height = static_cast(resolution.height)}; } void FrameGeneratorCapturer::Start() { @@ -266,6 +168,14 @@ void FrameGeneratorCapturer::ChangeFramerate(int target_framerate) { target_capture_fps_ = std::min(source_fps_, target_framerate); } +int FrameGeneratorCapturer::GetFrameWidth() const { + return static_cast(frame_generator_->GetResolution().width); +} + +int FrameGeneratorCapturer::GetFrameHeight() const { + return static_cast(frame_generator_->GetResolution().height); +} + void FrameGeneratorCapturer::OnOutputFormatRequest( int width, int height, diff --git a/third_party/libwebrtc/test/frame_generator_capturer.h b/third_party/libwebrtc/test/frame_generator_capturer.h index e310e40129e7f..b1fd7ebfc737c 100644 --- a/third_party/libwebrtc/test/frame_generator_capturer.h +++ b/third_party/libwebrtc/test/frame_generator_capturer.h @@ -10,81 +10,27 @@ #ifndef TEST_FRAME_GENERATOR_CAPTURER_H_ #define TEST_FRAME_GENERATOR_CAPTURER_H_ +#include +#include #include -#include +#include "absl/types/optional.h" #include "api/task_queue/task_queue_factory.h" #include "api/test/frame_generator_interface.h" +#include "api/video/color_space.h" #include "api/video/video_frame.h" +#include "api/video/video_rotation.h" +#include "api/video/video_sink_interface.h" +#include "api/video/video_source_interface.h" #include "rtc_base/synchronization/mutex.h" #include "rtc_base/task_queue.h" #include "rtc_base/task_utils/repeating_task.h" +#include "rtc_base/thread_annotations.h" #include "system_wrappers/include/clock.h" #include "test/test_video_capturer.h" namespace webrtc { - namespace test { -namespace frame_gen_cap_impl { -template -class AutoOpt : public absl::optional { - public: - using absl::optional::optional; - T* operator->() { - if (!absl::optional::has_value()) - this->emplace(T()); - return absl::optional::operator->(); - } -}; -} // namespace frame_gen_cap_impl -struct FrameGeneratorCapturerConfig { - struct SquaresVideo { - int framerate = 30; - FrameGeneratorInterface::OutputType pixel_format = - FrameGeneratorInterface::OutputType::kI420; - int width = 320; - int height = 180; - int num_squares = 10; - }; - - struct SquareSlides { - int framerate = 30; - TimeDelta change_interval = TimeDelta::Seconds(10); - int width = 1600; - int height = 1200; - }; - - struct VideoFile { - int framerate = 30; - std::string name; - // Must be set to width and height of the source video file. - int width = 0; - int height = 0; - }; - - struct ImageSlides { - int framerate = 30; - TimeDelta change_interval = TimeDelta::Seconds(10); - struct Crop { - TimeDelta scroll_duration = TimeDelta::Seconds(0); - absl::optional width; - absl::optional height; - } crop; - int width = 1850; - int height = 1110; - std::vector paths = { - "web_screenshot_1850_1110", - "presentation_1850_1110", - "photo_1850_1110", - "difficult_photo_1850_1110", - }; - }; - - frame_gen_cap_impl::AutoOpt squares_video; - frame_gen_cap_impl::AutoOpt squares_slides; - frame_gen_cap_impl::AutoOpt video_file; - frame_gen_cap_impl::AutoOpt image_slides; -}; class FrameGeneratorCapturer : public TestVideoCapturer { public: @@ -106,37 +52,19 @@ class FrameGeneratorCapturer : public TestVideoCapturer { TaskQueueFactory& task_queue_factory); virtual ~FrameGeneratorCapturer(); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquaresVideo config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::SquareSlides config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::VideoFile config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - FrameGeneratorCapturerConfig::ImageSlides config); - static std::unique_ptr Create( - Clock* clock, - TaskQueueFactory& task_queue_factory, - const FrameGeneratorCapturerConfig& config); - void Start(); void Stop(); void ChangeResolution(size_t width, size_t height); void ChangeFramerate(int target_framerate); + int GetFrameWidth() const override; + int GetFrameHeight() const override; + struct Resolution { int width; int height; }; - absl::optional GetResolution(); + absl::optional GetResolution() const; void OnOutputFormatRequest(int width, int height, @@ -178,9 +106,6 @@ class FrameGeneratorCapturer : public TestVideoCapturer { int64_t first_frame_capture_time_; - Mutex stats_lock_; - absl::optional source_resolution_ RTC_GUARDED_BY(&stats_lock_); - // Must be the last field, so it will be deconstructed first as tasks // in the TaskQueue access other fields of the instance of this class. rtc::TaskQueue task_queue_; diff --git a/third_party/libwebrtc/test/frame_generator_capturer_unittest.cc b/third_party/libwebrtc/test/frame_generator_capturer_unittest.cc index d8371f4efd4fa..8bf70cffd532c 100644 --- a/third_party/libwebrtc/test/frame_generator_capturer_unittest.cc +++ b/third_party/libwebrtc/test/frame_generator_capturer_unittest.cc @@ -9,6 +9,8 @@ */ #include "test/frame_generator_capturer.h" + +#include "test/create_frame_generator_capturer.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/time_controller/simulated_time_controller.h" @@ -36,7 +38,7 @@ TEST(FrameGeneratorCapturerTest, CreateFromConfig) { config.squares_video->width = 300; config.squares_video->height = 200; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); testing::StrictMock mock_sink; capturer->AddOrUpdateSink(&mock_sink, rtc::VideoSinkWants()); @@ -52,7 +54,7 @@ TEST(FrameGeneratorCapturerTest, OnOutputFormatRequest) { config.squares_video->width = kWidth; config.squares_video->height = kHeight; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); testing::StrictMock mock_sink; capturer->AddOrUpdateSink(&mock_sink, rtc::VideoSinkWants()); @@ -69,9 +71,11 @@ TEST(FrameGeneratorCapturerTest, ChangeResolution) { config.squares_video->width = kWidth; config.squares_video->height = kHeight; config.squares_video->framerate = 20; - auto capturer = FrameGeneratorCapturer::Create( + auto capturer = CreateFrameGeneratorCapturer( time.GetClock(), *time.GetTaskQueueFactory(), config); - EXPECT_FALSE(capturer->GetResolution()); + EXPECT_TRUE(capturer->GetResolution()); + EXPECT_EQ(kWidth, capturer->GetResolution()->width); + EXPECT_EQ(kHeight, capturer->GetResolution()->height); capturer->Start(); time.AdvanceTime(TimeDelta::Seconds(1)); ASSERT_TRUE(capturer->GetResolution()); diff --git a/third_party/libwebrtc/test/fuzzers/utils/BUILD.gn b/third_party/libwebrtc/test/fuzzers/utils/BUILD.gn index c5744fc33bbdd..dfb617857c33f 100644 --- a/third_party/libwebrtc/test/fuzzers/utils/BUILD.gn +++ b/third_party/libwebrtc/test/fuzzers/utils/BUILD.gn @@ -41,6 +41,7 @@ rtc_library("rtp_replayer") { "../../../test:run_test_interface", "../../../test:test_renderer", "../../../test:test_support", + "../../../test:test_video_capturer", "../../../test:video_test_common", ] absl_deps = [ "//third_party/abseil-cpp/absl/memory:memory" ] diff --git a/third_party/libwebrtc/test/mac_capturer.h b/third_party/libwebrtc/test/mac_capturer.h index 3d7ee77b45700..35cd1ccd1e14e 100644 --- a/third_party/libwebrtc/test/mac_capturer.h +++ b/third_party/libwebrtc/test/mac_capturer.h @@ -10,6 +10,7 @@ #ifndef TEST_MAC_CAPTURER_H_ #define TEST_MAC_CAPTURER_H_ +#include #include #include @@ -33,6 +34,9 @@ class MacCapturer : public TestVideoCapturer, void OnFrame(const VideoFrame& frame) override; + int GetFrameWidth() const override { return static_cast(width_); } + int GetFrameHeight() const override { return static_cast(height_); } + private: MacCapturer(size_t width, size_t height, @@ -40,6 +44,8 @@ class MacCapturer : public TestVideoCapturer, size_t capture_device_index); void Destroy(); + size_t width_; + size_t height_; void* capturer_; void* adapter_; }; diff --git a/third_party/libwebrtc/test/mac_capturer.mm b/third_party/libwebrtc/test/mac_capturer.mm index da8e9b76b68bd..9b14f28c2afda 100644 --- a/third_party/libwebrtc/test/mac_capturer.mm +++ b/third_party/libwebrtc/test/mac_capturer.mm @@ -64,6 +64,8 @@ - (void)capturer:(RTC_OBJC_TYPE(RTCVideoCapturer) *)capturer size_t height, size_t target_fps, size_t capture_device_index) { + width_ = width; + height_ = height; RTCTestVideoSourceAdapter *adapter = [[RTCTestVideoSourceAdapter alloc] init]; adapter_ = (__bridge_retained void *)adapter; adapter.capturer = this; diff --git a/third_party/libwebrtc/test/network/BUILD.gn b/third_party/libwebrtc/test/network/BUILD.gn index 20b17bc804110..5a6cb31f4b65f 100644 --- a/third_party/libwebrtc/test/network/BUILD.gn +++ b/third_party/libwebrtc/test/network/BUILD.gn @@ -126,7 +126,7 @@ if (rtc_include_tests && !build_with_chromium) { "../../call:simulated_network", "../../media:rtc_audio_video", "../../media:rtc_media_engine_defaults", - "../../modules/audio_device:audio_device_impl", + "../../modules/audio_device:test_audio_device_module", "../../p2p:rtc_p2p", "../../pc:pc_test_utils", "../../pc:peerconnection_wrapper", diff --git a/third_party/libwebrtc/test/pc/e2e/BUILD.gn b/third_party/libwebrtc/test/pc/e2e/BUILD.gn index 635b917ba0c43..ebe4d9b08c530 100644 --- a/third_party/libwebrtc/test/pc/e2e/BUILD.gn +++ b/third_party/libwebrtc/test/pc/e2e/BUILD.gn @@ -49,7 +49,7 @@ if (!build_with_chromium) { ] deps = [ "../../../api/test/pclf:media_configuration", - "../../../modules/audio_device:audio_device_impl", + "../../../modules/audio_device:test_audio_device_module", "../../../rtc_base:swap_queue", ] } @@ -107,7 +107,7 @@ if (!build_with_chromium) { "../../../api/video_codecs:builtin_video_encoder_factory", "../../../media:rtc_audio_video", "../../../media:rtc_media_engine_defaults", - "../../../modules/audio_device:audio_device_impl", + "../../../modules/audio_device:test_audio_device_module", "../../../modules/audio_processing/aec_dump", "../../../p2p:rtc_p2p", "../../../rtc_base:rtc_task_queue", @@ -121,18 +121,29 @@ if (!build_with_chromium) { ] } + rtc_library("test_video_capturer_video_track_source") { + testonly = true + sources = [ "media/test_video_capturer_video_track_source.h" ] + deps = [ + "../..:test_video_capturer", + "../../../api:sequence_checker", + "../../../api/test/video:test_video_track_source", + "../../../api/video:video_frame", + ] + } + rtc_library("media_helper") { testonly = true sources = [ "media/media_helper.cc", "media/media_helper.h", - "media/test_video_capturer_video_track_source.h", ] deps = [ ":test_peer", + ":test_video_capturer_video_track_source", "../..:fileutils", + "../..:frame_generator_capturer", "../..:platform_video_capturer", - "../..:video_test_common", "../../../api:create_frame_generator", "../../../api:frame_generator_api", "../../../api:media_stream_interface", diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn b/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn index 91af64e5a415f..6ce0c4968b63d 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/BUILD.gn @@ -382,6 +382,7 @@ rtc_library("video_quality_analyzer_injection_helper") { ":video_dumping", "../../../..:fixed_fps_video_frame_writer_adapter", "../../../..:test_renderer", + "../../../..:test_video_capturer", "../../../..:video_test_common", "../../../..:video_test_support", "../../../../../api:array_view", diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc index ebd20b6c5e504..2c81c5dc05dc6 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc @@ -211,6 +211,12 @@ uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured( } StreamState* state = &stream_states_.at(stream_index); state->PushBack(frame_id); + absl::optional time_between_captured_frames = absl::nullopt; + if (state->last_captured_frame_time().has_value()) { + time_between_captured_frames = + captured_time - *state->last_captured_frame_time(); + } + state->SetLastCapturedFrameTime(captured_time); // Update frames in flight info. auto it = captured_frames_in_flight_.find(frame_id); if (it != captured_frames_in_flight_.end()) { @@ -247,6 +253,7 @@ uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured( } captured_frames_in_flight_.emplace( frame_id, FrameInFlight(stream_index, frame_id, captured_time, + time_between_captured_frames, std::move(frame_receivers_indexes))); // Store local copy of the frame with frame_id set. VideoFrame local_frame(frame); @@ -337,6 +344,13 @@ void DefaultVideoQualityAnalyzer::OnFrameEncoded( } } Timestamp now = Now(); + StreamState& state = stream_states_.at(frame_in_flight.stream()); + absl::optional time_between_encoded_frames = absl::nullopt; + if (state.last_encoded_frame_time().has_value()) { + time_between_encoded_frames = now - *state.last_encoded_frame_time(); + } + state.SetLastEncodedFrameTime(now); + StreamCodecInfo used_encoder; used_encoder.codec_name = stats.encoder_name; used_encoder.first_frame_id = frame_id; @@ -350,8 +364,9 @@ void DefaultVideoQualityAnalyzer::OnFrameEncoded( size_t stream_index = encoded_image.SpatialIndex().value_or( encoded_image.SimulcastIndex().value_or(0)); frame_in_flight.OnFrameEncoded( - now, encoded_image._frameType, DataSize::Bytes(encoded_image.size()), - stats.target_encode_bitrate, stream_index, stats.qp, used_encoder); + now, time_between_encoded_frames, encoded_image._frameType, + DataSize::Bytes(encoded_image.size()), stats.target_encode_bitrate, + stream_index, stats.qp, used_encoder); if (options_.report_infra_metrics) { analyzer_stats_.on_frame_encoded_processing_time_ms.AddSample( @@ -723,14 +738,14 @@ void DefaultVideoQualityAnalyzer::OnPauseAllStreamsFrom( absl::string_view sender_peer_name, absl::string_view receiver_peer_name) { MutexLock lock(&mutex_); - RTC_CHECK(peers_->HasName(sender_peer_name)); - size_t sender_peer_index = peers_->index(sender_peer_name); - RTC_CHECK(peers_->HasName(receiver_peer_name)); - size_t receiver_peer_index = peers_->index(receiver_peer_name); - - for (auto& [unused, stream_state] : stream_states_) { - if (stream_state.sender() == sender_peer_index) { - stream_state.GetPausableState(receiver_peer_index)->Pause(); + if (peers_->HasName(sender_peer_name) && + peers_->HasName(receiver_peer_name)) { + size_t sender_peer_index = peers_->index(sender_peer_name); + size_t receiver_peer_index = peers_->index(receiver_peer_name); + for (auto& [unused, stream_state] : stream_states_) { + if (stream_state.sender() == sender_peer_index) { + stream_state.GetPausableState(receiver_peer_index)->Pause(); + } } } } @@ -739,14 +754,14 @@ void DefaultVideoQualityAnalyzer::OnResumeAllStreamsFrom( absl::string_view sender_peer_name, absl::string_view receiver_peer_name) { MutexLock lock(&mutex_); - RTC_CHECK(peers_->HasName(sender_peer_name)); - size_t sender_peer_index = peers_->index(sender_peer_name); - RTC_CHECK(peers_->HasName(receiver_peer_name)); - size_t receiver_peer_index = peers_->index(receiver_peer_name); - - for (auto& [unused, stream_state] : stream_states_) { - if (stream_state.sender() == sender_peer_index) { - stream_state.GetPausableState(receiver_peer_index)->Resume(); + if (peers_->HasName(sender_peer_name) && + peers_->HasName(receiver_peer_name)) { + size_t sender_peer_index = peers_->index(sender_peer_name); + size_t receiver_peer_index = peers_->index(receiver_peer_name); + for (auto& [unused, stream_state] : stream_states_) { + if (stream_state.sender() == sender_peer_index) { + stream_state.GetPausableState(receiver_peer_index)->Resume(); + } } } } @@ -828,19 +843,17 @@ void DefaultVideoQualityAnalyzer::Stop() { } std::string DefaultVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) { - MutexLock lock1(&mutex_); - auto it = captured_frames_in_flight_.find(frame_id); - if (it != captured_frames_in_flight_.end()) { - return streams_.name(it->second.stream()); - } - for (auto hist_it = stream_to_frame_id_history_.begin(); - hist_it != stream_to_frame_id_history_.end(); ++hist_it) { - auto hist_set_it = hist_it->second.find(frame_id); - if (hist_set_it != hist_it->second.end()) { - return streams_.name(hist_it->first); - } - } - RTC_CHECK(false) << "Unknown frame_id=" << frame_id; + MutexLock lock(&mutex_); + return GetStreamLabelInternal(frame_id); +} + +std::string DefaultVideoQualityAnalyzer::GetSenderPeerName( + uint16_t frame_id) const { + MutexLock lock(&mutex_); + std::string stream_label = GetStreamLabelInternal(frame_id); + size_t stream_index = streams_.index(stream_label); + size_t sender_peer_index = stream_states_.at(stream_index).sender(); + return peers_->name(sender_peer_index); } std::set DefaultVideoQualityAnalyzer::GetKnownVideoStreams() const { @@ -1306,6 +1319,22 @@ std::string DefaultVideoQualityAnalyzer::ToMetricName( return out.str(); } +std::string DefaultVideoQualityAnalyzer::GetStreamLabelInternal( + uint16_t frame_id) const { + auto it = captured_frames_in_flight_.find(frame_id); + if (it != captured_frames_in_flight_.end()) { + return streams_.name(it->second.stream()); + } + for (auto hist_it = stream_to_frame_id_history_.begin(); + hist_it != stream_to_frame_id_history_.end(); ++hist_it) { + auto hist_set_it = hist_it->second.find(frame_id); + if (hist_set_it != hist_it->second.end()) { + return streams_.name(hist_it->first); + } + } + RTC_CHECK(false) << "Unknown frame_id=" << frame_id; +} + double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() { return cpu_measurer_.GetCpuUsagePercent(); } diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h index 1ea59bdfca54d..060a836ccfd90 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "api/array_view.h" @@ -88,6 +89,7 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { void Stop() override; std::string GetStreamLabel(uint16_t frame_id) override; + std::string GetSenderPeerName(uint16_t frame_id) const override; void OnStatsReports( absl::string_view pc_label, const rtc::scoped_refptr& report) override {} @@ -149,6 +151,8 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { // backward compatibility by metrics naming for 2 peers cases. std::string ToMetricName(const InternalStatsKey& key) const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + std::string GetStreamLabelInternal(uint16_t frame_id) const + RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); static const uint16_t kStartingFrameId = 1; @@ -178,7 +182,7 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { // 4. There too many frames in flight for current video stream and X is the // oldest frame id in this stream. In such case only the frame content // will be removed, but the map entry will be preserved. - std::map captured_frames_in_flight_ + std::unordered_map captured_frames_in_flight_ RTC_GUARDED_BY(mutex_); // Global frames count for all video streams. FrameCounters frame_counters_ RTC_GUARDED_BY(mutex_); @@ -190,19 +194,19 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { std::map stream_frame_counters_ RTC_GUARDED_BY(mutex_); // Map from stream index in `streams_` to its StreamState. - std::map stream_states_ RTC_GUARDED_BY(mutex_); + std::unordered_map stream_states_ RTC_GUARDED_BY(mutex_); // Map from stream index in `streams_` to sender peer index in `peers_`. - std::map stream_to_sender_ RTC_GUARDED_BY(mutex_); + std::unordered_map stream_to_sender_ RTC_GUARDED_BY(mutex_); // Stores history mapping between stream index in `streams_` and frame ids. // Updated when frame id overlap. It required to properly return stream label // after 1st frame from simulcast streams was already rendered and last is // still encoding. - std::map> stream_to_frame_id_history_ + std::unordered_map> stream_to_frame_id_history_ RTC_GUARDED_BY(mutex_); // Map from stream index to the list of frames as they were met in the stream. - std::map> stream_to_frame_id_full_history_ - RTC_GUARDED_BY(mutex_); + std::unordered_map> + stream_to_frame_id_full_history_ RTC_GUARDED_BY(mutex_); AnalyzerStats analyzer_stats_ RTC_GUARDED_BY(mutex_); DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer_; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc index b0ed041301f23..056bd73f88b4b 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.cc @@ -16,6 +16,7 @@ #include "absl/types/optional.h" #include "api/units/data_size.h" +#include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "api/video/video_frame.h" #include "api/video/video_frame_type.h" @@ -36,14 +37,17 @@ absl::optional MaybeGetValue(const std::unordered_map& map, } // namespace -FrameInFlight::FrameInFlight(size_t stream, - uint16_t frame_id, - Timestamp captured_time, - std::set expected_receivers) +FrameInFlight::FrameInFlight( + size_t stream, + uint16_t frame_id, + Timestamp captured_time, + absl::optional time_between_captured_frames, + std::set expected_receivers) : stream_(stream), expected_receivers_(std::move(expected_receivers)), frame_id_(frame_id), - captured_time_(captured_time) {} + captured_time_(captured_time), + time_between_captured_frames_(time_between_captured_frames) {} std::vector FrameInFlight::GetPeersWhichDidntReceive() const { std::vector out; @@ -73,14 +77,21 @@ bool FrameInFlight::HaveAllPeersReceived() const { return true; } -void FrameInFlight::OnFrameEncoded(webrtc::Timestamp time, - VideoFrameType frame_type, - DataSize encoded_image_size, - uint32_t target_encode_bitrate, - int stream_index, - int qp, - StreamCodecInfo used_encoder) { +void FrameInFlight::OnFrameEncoded( + webrtc::Timestamp time, + absl::optional time_between_encoded_frames, + VideoFrameType frame_type, + DataSize encoded_image_size, + uint32_t target_encode_bitrate, + int stream_index, + int qp, + StreamCodecInfo used_encoder) { encoded_time_ = time; + if (time_between_encoded_frames.has_value()) { + time_between_encoded_frames_ = + time_between_encoded_frames_.value_or(TimeDelta::Zero()) + + *time_between_encoded_frames; + } frame_type_ = frame_type; encoded_image_size_ = encoded_image_size; target_encode_bitrate_ += target_encode_bitrate; @@ -171,6 +182,8 @@ FrameStats FrameInFlight::GetStatsForPeer(size_t peer) const { RTC_DCHECK(!IsSuperfluous(peer)) << "This frame is superfluous for peer " << peer; FrameStats stats(frame_id_, captured_time_); + stats.time_between_captured_frames = time_between_captured_frames_; + stats.time_between_encoded_frames = time_between_encoded_frames_; stats.pre_encode_time = pre_encode_time_; stats.encoded_time = encoded_time_; stats.target_encode_bitrate = target_encode_bitrate_; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h index 06552c7013cd6..d73de29afb4db 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frame_in_flight.h @@ -34,9 +34,10 @@ struct ReceiverFrameStats { Timestamp decode_start_time = Timestamp::MinusInfinity(); Timestamp decode_end_time = Timestamp::MinusInfinity(); Timestamp rendered_time = Timestamp::MinusInfinity(); - Timestamp prev_frame_rendered_time = Timestamp::MinusInfinity(); - TimeDelta time_between_rendered_frames = TimeDelta::Zero(); + // Will be set if there is frame rendered before this one. + absl::optional prev_frame_rendered_time = absl::nullopt; + absl::optional time_between_rendered_frames = absl::nullopt; // Type and encoded size of received frame. VideoFrameType frame_type = VideoFrameType::kEmptyFrame; @@ -68,6 +69,7 @@ class FrameInFlight { FrameInFlight(size_t stream, uint16_t frame_id, Timestamp captured_time, + absl::optional time_between_captured_frames, std::set expected_receivers); size_t stream() const { return stream_; } @@ -89,6 +91,7 @@ class FrameInFlight { void SetPreEncodeTime(Timestamp time) { pre_encode_time_ = time; } void OnFrameEncoded(Timestamp time, + absl::optional time_between_encoded_frames, VideoFrameType frame_type, DataSize encoded_image_size, uint32_t target_encode_bitrate, @@ -156,14 +159,16 @@ class FrameInFlight { // any peer or can be safely deleted. It is responsibility of the user of this // object to decide when it should be deleted. std::set expected_receivers_; - // Store frame id separately because `frame_` can be removed when we have too - // much memory consuption. uint16_t frame_id_ = VideoFrame::kNotSetId; // Frame events timestamp. Timestamp captured_time_; Timestamp pre_encode_time_ = Timestamp::MinusInfinity(); Timestamp encoded_time_ = Timestamp::MinusInfinity(); + + absl::optional time_between_captured_frames_ = absl::nullopt; + absl::optional time_between_encoded_frames_ = absl::nullopt; + // Type and encoded size of sent frame. VideoFrameType frame_type_ = VideoFrameType::kEmptyFrame; DataSize encoded_image_size_ = DataSize::Bytes(0); diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc index 7ea2a2a90c81a..eb10aef34c152 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc @@ -464,6 +464,11 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison( StatsSample(ssim, frame_stats.received_time, metadata)); } stats->capture_frame_rate.AddEvent(frame_stats.captured_time); + if (frame_stats.time_between_captured_frames.has_value()) { + stats->time_between_captured_frames_ms.AddSample( + StatsSample(*frame_stats.time_between_captured_frames, + frame_stats.captured_time, metadata)); + } // Compute dropped phase for dropped frame if (comparison.type == FrameComparisonType::kDroppedFrame) { @@ -487,6 +492,11 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison( StatsSample(frame_stats.encoded_time - frame_stats.pre_encode_time, frame_stats.encoded_time, metadata)); stats->encode_frame_rate.AddEvent(frame_stats.encoded_time); + if (frame_stats.time_between_encoded_frames.has_value()) { + stats->time_between_encoded_frames_ms.AddSample( + StatsSample(*frame_stats.time_between_encoded_frames, + frame_stats.encoded_time, metadata)); + } stats->total_encoded_images_payload += frame_stats.encoded_image_size.bytes(); stats->target_encode_bitrate.AddSample(StatsSample( @@ -544,25 +554,26 @@ void DefaultVideoQualityAnalyzerFramesComparator::ProcessComparison( frame_stats.decode_end_time, metadata)); } - if (frame_stats.prev_frame_rendered_time.IsFinite() && + if (frame_stats.prev_frame_rendered_time.has_value() && frame_stats.rendered_time.IsFinite()) { + RTC_DCHECK(frame_stats.time_between_rendered_frames.has_value()); stats->time_between_rendered_frames_ms.AddSample( - StatsSample(frame_stats.time_between_rendered_frames, + StatsSample(*frame_stats.time_between_rendered_frames, frame_stats.rendered_time, metadata)); TimeDelta average_time_between_rendered_frames = TimeDelta::Millis( stats->time_between_rendered_frames_ms.GetAverage()); - if (frame_stats.time_between_rendered_frames > + if (*frame_stats.time_between_rendered_frames > std::max(kFreezeThreshold + average_time_between_rendered_frames, 3 * average_time_between_rendered_frames)) { stats->freeze_time_ms.AddSample( - StatsSample(frame_stats.time_between_rendered_frames, + StatsSample(*frame_stats.time_between_rendered_frames, frame_stats.rendered_time, metadata)); auto freeze_end_it = stream_last_freeze_end_time_.find(comparison.stats_key); RTC_DCHECK(freeze_end_it != stream_last_freeze_end_time_.end()); // TODO(bugs.webrtc.org/14995): rethink this metric for paused stream. stats->time_between_freezes_ms.AddSample(StatsSample( - frame_stats.prev_frame_rendered_time - freeze_end_it->second, + *frame_stats.prev_frame_rendered_time - freeze_end_it->second, frame_stats.rendered_time, metadata)); freeze_end_it->second = frame_stats.rendered_time; } diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc index 0024e794a5e95..2656bf5d441ea 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator_test.cc @@ -1604,13 +1604,16 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest, // Add 5 frames which were rendered with 30 fps (~30ms between frames) // Frame ids are in [1..5] and last frame is with 120ms offset from first. - Timestamp prev_frame_rendered_time = Timestamp::MinusInfinity(); + absl::optional prev_frame_rendered_time = absl::nullopt; for (int i = 0; i < 5; ++i) { FrameStats frame_stats = FrameStatsWith10msDeltaBetweenPhasesAnd10x10Frame( /*frame_id=*/i + 1, stream_start_time + TimeDelta::Millis(30 * i)); frame_stats.prev_frame_rendered_time = prev_frame_rendered_time; frame_stats.time_between_rendered_frames = - frame_stats.rendered_time - prev_frame_rendered_time; + prev_frame_rendered_time.has_value() + ? absl::optional(frame_stats.rendered_time - + *prev_frame_rendered_time) + : absl::nullopt; prev_frame_rendered_time = frame_stats.rendered_time; comparator.AddComparison(stats_key, @@ -1626,7 +1629,7 @@ TEST(DefaultVideoQualityAnalyzerFramesComparatorTest, /*frame_id=*/10, stream_start_time + TimeDelta::Millis(120 + 300)); freeze_frame_stats.prev_frame_rendered_time = prev_frame_rendered_time; freeze_frame_stats.time_between_rendered_frames = - freeze_frame_stats.rendered_time - prev_frame_rendered_time; + freeze_frame_stats.rendered_time - *prev_frame_rendered_time; comparator.AddComparison(stats_key, /*skipped_between_rendered=*/4, diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h index b4254805b03e9..88c0335b5ac0d 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_internal_shared_objects.h @@ -57,11 +57,12 @@ struct FrameStats { Timestamp decode_start_time = Timestamp::MinusInfinity(); Timestamp decode_end_time = Timestamp::MinusInfinity(); Timestamp rendered_time = Timestamp::MinusInfinity(); - Timestamp prev_frame_rendered_time = Timestamp::MinusInfinity(); - // Time between this and previous rendered frame excluding time when related - // stream was paused for related receiver. - TimeDelta time_between_rendered_frames = TimeDelta::Zero(); + // Next timings are set if and only if previous frame exist. + absl::optional prev_frame_rendered_time = absl::nullopt; + absl::optional time_between_captured_frames = absl::nullopt; + absl::optional time_between_encoded_frames = absl::nullopt; + absl::optional time_between_rendered_frames = absl::nullopt; VideoFrameType encoded_frame_type = VideoFrameType::kEmptyFrame; DataSize encoded_image_size = DataSize::Bytes(0); diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h index ef6ac4bf7abbb..73cbcc03df5ac 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h @@ -126,6 +126,9 @@ struct StreamStats { SamplesStatsCounter total_delay_incl_transport_ms; // Time between frames out from renderer. SamplesStatsCounter time_between_rendered_frames_ms; + SamplesStatsCounter time_between_captured_frames_ms; + // Time between frames out from encoder. + SamplesStatsCounter time_between_encoded_frames_ms; SamplesRateCounter capture_frame_rate; SamplesRateCounter encode_frame_rate; SamplesStatsCounter encode_time_ms; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h index 190432cfb65ed..22fbfd4a40f5c 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_stream_state.h @@ -70,6 +70,20 @@ class StreamState { return frame_ids_.size(kAliveFramesQueueIndex); } + void SetLastCapturedFrameTime(Timestamp time) { + last_captured_frame_time_ = time; + } + absl::optional last_captured_frame_time() const { + return last_captured_frame_time_; + } + + void SetLastEncodedFrameTime(Timestamp time) { + last_encoded_frame_time_ = time; + } + absl::optional last_encoded_frame_time() const { + return last_encoded_frame_time_; + } + void SetLastRenderedFrameTime(size_t peer, Timestamp time); absl::optional last_rendered_frame_time(size_t peer) const; @@ -99,6 +113,8 @@ class StreamState { // frame_id2 and consider those frames as dropped and then compare received // frame with the one from `FrameInFlight` with id frame_id3. MultiReaderQueue frame_ids_; + absl::optional last_captured_frame_time_ = absl::nullopt; + absl::optional last_encoded_frame_time_ = absl::nullopt; std::unordered_map last_rendered_frame_time_; // Mapping from peer's index to pausable state for this receiver. std::unordered_map pausable_state_; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc index a66d1a9a5be7c..7b52bad0a8245 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc @@ -2147,9 +2147,11 @@ TEST_F(DefaultVideoQualityAnalyzerSimulatedTimeTest, // TODO(bugs.webrtc.org/14995): value should exclude pause EXPECT_THAT(GetTimeSortedValues(bob_stream_stats.time_between_freezes_ms), ElementsAre(2950.0)); - // TODO(bugs.webrtc.org/14995): Fix capture_frame_rate (has to be ~20.0) + EXPECT_THAT(bob_stream_stats.time_between_captured_frames_ms.GetAverage(), + 50.0); + EXPECT_THAT(bob_stream_stats.time_between_encoded_frames_ms.GetAverage(), + 50.0); ExpectRateIs(bob_stream_stats.capture_frame_rate, 13.559322); - // TODO(bugs.webrtc.org/14995): Fix encode_frame_rate (has to be ~20.0) ExpectRateIs(bob_stream_stats.encode_frame_rate, 13.559322); EXPECT_DOUBLE_EQ(bob_stream_stats.harmonic_framerate_fps, 20); @@ -2208,22 +2210,22 @@ TEST_F(DefaultVideoQualityAnalyzerSimulatedTimeTest, std::map streams_stats = analyzer.GetStats(); std::map frame_counters = analyzer.GetPerStreamCounters(); - StreamStats bob_stream_stats1 = + StreamStats bob_stream_stats_1 = streams_stats.at(StatsKey("alice_video_1", "bob")); FrameCounters bob_frame_counters1 = frame_counters.at(StatsKey("alice_video_1", "bob")); EXPECT_THAT(bob_frame_counters1.dropped, Eq(0)); EXPECT_THAT(bob_frame_counters1.rendered, Eq(40)); - EXPECT_THAT(GetTimeSortedValues(bob_stream_stats1.freeze_time_ms), + EXPECT_THAT(GetTimeSortedValues(bob_stream_stats_1.freeze_time_ms), ElementsAre(0.0)); // TODO(bugs.webrtc.org/14995): value should exclude pause - EXPECT_THAT(GetTimeSortedValues(bob_stream_stats1.time_between_freezes_ms), + EXPECT_THAT(GetTimeSortedValues(bob_stream_stats_1.time_between_freezes_ms), ElementsAre(2950.0)); - // TODO(bugs.webrtc.org/14995): Fix capture_frame_rate (has to be ~20.0) - ExpectRateIs(bob_stream_stats1.capture_frame_rate, 13.559322); - // TODO(bugs.webrtc.org/14995): Fix encode_frame_rate (has to be ~20.0) - ExpectRateIs(bob_stream_stats1.encode_frame_rate, 13.559322); - EXPECT_DOUBLE_EQ(bob_stream_stats1.harmonic_framerate_fps, 20.0); + EXPECT_THAT(bob_stream_stats_1.time_between_captured_frames_ms.GetAverage(), + 50.0); + EXPECT_THAT(bob_stream_stats_1.time_between_encoded_frames_ms.GetAverage(), + 50.0); + EXPECT_DOUBLE_EQ(bob_stream_stats_1.harmonic_framerate_fps, 20.0); // Bob should have 20 fps without freeze on both streams. StreamStats bob_stream_stats_2 = @@ -2237,10 +2239,10 @@ TEST_F(DefaultVideoQualityAnalyzerSimulatedTimeTest, // TODO(bugs.webrtc.org/14995): value should exclude pause EXPECT_THAT(GetTimeSortedValues(bob_stream_stats_2.time_between_freezes_ms), ElementsAre(2950.0)); - // TODO(bugs.webrtc.org/14995): Fix capture_frame_rate (has to be ~20.0) - ExpectRateIs(bob_stream_stats_2.capture_frame_rate, 13.559322); - // TODO(bugs.webrtc.org/14995): Fix encode_frame_rate (has to be ~20.0) - ExpectRateIs(bob_stream_stats_2.encode_frame_rate, 13.559322); + EXPECT_THAT(bob_stream_stats_2.time_between_captured_frames_ms.GetAverage(), + 50.0); + EXPECT_THAT(bob_stream_stats_2.time_between_encoded_frames_ms.GetAverage(), + 50.0); EXPECT_DOUBLE_EQ(bob_stream_stats_2.harmonic_framerate_fps, 20.0); } @@ -2373,5 +2375,38 @@ TEST_F(DefaultVideoQualityAnalyzerSimulatedTimeTest, EXPECT_EQ(frame_counters.dropped, 0); } +TEST(DefaultVideoQualityAnalyzerTest, CheckFrameSenderPeerName) { + constexpr char kAlice[] = "alice"; + constexpr char kBob[] = "bob"; + constexpr char kAliceStreamLabel[] = "alice-video"; + constexpr char kBobStreamLabel[] = "bob-video"; + std::unique_ptr frame_generator = + test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight, + /*type=*/absl::nullopt, + /*num_squares=*/absl::nullopt); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), + test::GetGlobalMetricsLogger(), + AnalyzerOptionsForTest()); + analyzer.Start("test_case", std::vector{kAlice, kBob}, + kAnalyzerMaxThreadsCount); + + VideoFrame frame_alice = NextFrame(frame_generator.get(), /*timestamp_us=*/1); + VideoFrame frame_bob = NextFrame(frame_generator.get(), /*timestamp_us=*/2); + frame_alice.set_id( + analyzer.OnFrameCaptured(kAlice, kAliceStreamLabel, frame_alice)); + frame_bob.set_id(analyzer.OnFrameCaptured(kBob, kBobStreamLabel, frame_bob)); + std::string sender_alice = analyzer.GetSenderPeerName(frame_alice.id()); + std::string sender_bob = analyzer.GetSenderPeerName(frame_bob.id()); + + // Give analyzer some time to process frames on async thread. The computations + // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it + // means we have an issue! + SleepMs(100); + analyzer.Stop(); + + EXPECT_EQ(sender_alice, kAlice); + EXPECT_EQ(sender_bob, kBob); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc index da9c53beb9823..1d8ec308748f4 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc @@ -32,6 +32,7 @@ uint16_t ExampleVideoQualityAnalyzer::OnFrameCaptured( if (frame_id == VideoFrame::kNotSetId) { frame_id = next_frame_id_++; } + stream_label_to_peer_name_[stream_label] = std::string(peer_name); auto it = frames_in_flight_.find(frame_id); if (it == frames_in_flight_.end()) { frames_in_flight_.insert(frame_id); @@ -130,6 +131,15 @@ std::string ExampleVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) { return it->second; } +std::string ExampleVideoQualityAnalyzer::GetSenderPeerName( + uint16_t frame_id) const { + MutexLock lock(&lock_); + auto it = frames_to_stream_label_.find(frame_id); + RTC_DCHECK(it != frames_to_stream_label_.end()) + << "Unknown frame_id=" << frame_id; + return stream_label_to_peer_name_.at(it->second); +} + uint64_t ExampleVideoQualityAnalyzer::frames_captured() const { MutexLock lock(&lock_); return frames_captured_; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h index af4868a961fff..56cefa5ab6dff 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h @@ -65,6 +65,7 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { const DecoderStats& stats) override; void Stop() override; std::string GetStreamLabel(uint16_t frame_id) override; + std::string GetSenderPeerName(uint16_t frame_id) const override; uint64_t frames_captured() const; uint64_t frames_pre_encoded() const; @@ -86,6 +87,8 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { // process frame id overlap. std::set frames_in_flight_ RTC_GUARDED_BY(lock_); std::map frames_to_stream_label_ RTC_GUARDED_BY(lock_); + std::map stream_label_to_peer_name_ + RTC_GUARDED_BY(lock_); uint16_t next_frame_id_ RTC_GUARDED_BY(lock_) = 1; uint64_t frames_captured_ RTC_GUARDED_BY(lock_) = 0; uint64_t frames_pre_encoded_ RTC_GUARDED_BY(lock_) = 0; diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc index 87c11886cce27..c61686f011c18 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc @@ -132,21 +132,11 @@ VideoQualityAnalyzerInjectionHelper::CreateFramePreprocessor( config.width, config.height))); } sinks_helper_.AddConfig(peer_name, config); - { - MutexLock lock(&mutex_); - known_video_configs_.insert({*config.stream_label, config}); - } return std::make_unique( peer_name, std::move(*config.stream_label), analyzer_.get(), std::move(sinks)); } -std::unique_ptr> -VideoQualityAnalyzerInjectionHelper::CreateVideoSink( - absl::string_view peer_name) { - return std::make_unique(peer_name, this); -} - std::unique_ptr VideoQualityAnalyzerInjectionHelper::CreateVideoSink( absl::string_view peer_name, @@ -163,24 +153,18 @@ void VideoQualityAnalyzerInjectionHelper::Start( int max_threads_count) { analyzer_->Start(std::move(test_case_name), peer_names, max_threads_count); extractor_->Start(peer_names.size()); - MutexLock lock(&mutex_); - peers_count_ = peer_names.size(); } void VideoQualityAnalyzerInjectionHelper::RegisterParticipantInCall( absl::string_view peer_name) { analyzer_->RegisterParticipantInCall(peer_name); extractor_->AddParticipantInCall(); - MutexLock lock(&mutex_); - peers_count_++; } void VideoQualityAnalyzerInjectionHelper::UnregisterParticipantInCall( absl::string_view peer_name) { analyzer_->UnregisterParticipantInCall(peer_name); extractor_->RemoveParticipantInCall(); - MutexLock lock(&mutex_); - peers_count_--; } void VideoQualityAnalyzerInjectionHelper::OnStatsReports( @@ -198,67 +182,5 @@ void VideoQualityAnalyzerInjectionHelper::Stop() { sinks_helper_.Clear(); } -void VideoQualityAnalyzerInjectionHelper::OnFrame(absl::string_view peer_name, - const VideoFrame& frame) { - if (IsDummyFrame(frame)) { - // This is dummy frame, so we don't need to process it further. - return; - } - // Copy entire video frame including video buffer to ensure that analyzer - // won't hold any WebRTC internal buffers. - VideoFrame frame_copy = frame; - frame_copy.set_video_frame_buffer( - I420Buffer::Copy(*frame.video_frame_buffer()->ToI420())); - analyzer_->OnFrameRendered(peer_name, frame_copy); - - if (frame.id() != VideoFrame::kNotSetId) { - std::string stream_label = analyzer_->GetStreamLabel(frame.id()); - std::vector>>* sinks = - PopulateSinks(ReceiverStream(peer_name, stream_label)); - if (sinks == nullptr) { - return; - } - for (auto& sink : *sinks) { - sink->OnFrame(frame); - } - } -} - -std::vector>>* -VideoQualityAnalyzerInjectionHelper::PopulateSinks( - const ReceiverStream& receiver_stream) { - MutexLock lock(&mutex_); - auto sinks_it = sinks_.find(receiver_stream); - if (sinks_it != sinks_.end()) { - return &sinks_it->second; - } - auto it = known_video_configs_.find(receiver_stream.stream_label); - RTC_DCHECK(it != known_video_configs_.end()) - << "No video config for stream " << receiver_stream.stream_label; - const VideoConfig& config = it->second; - - std::vector>> sinks; - if (config.output_dump_options.has_value()) { - std::unique_ptr writer = - config.output_dump_options->CreateOutputDumpVideoFrameWriter( - receiver_stream.stream_label, receiver_stream.peer_name, - config.GetResolution()); - if (config.output_dump_use_fixed_framerate) { - writer = std::make_unique( - config.fps, clock_, std::move(writer)); - } - sinks.push_back(std::make_unique( - writer.get(), config.output_dump_options->sampling_modulo())); - video_writers_.push_back(std::move(writer)); - } - if (config.show_on_screen) { - sinks.push_back(absl::WrapUnique( - test::VideoRenderer::Create((*config.stream_label + "-render").c_str(), - config.width, config.height))); - } - sinks_.insert({receiver_stream, std::move(sinks)}); - return &(sinks_.find(receiver_stream)->second); -} - } // namespace webrtc_pc_e2e } // namespace webrtc diff --git a/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h index 7421c8e4a7bb7..0039da8e86925 100644 --- a/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h +++ b/third_party/libwebrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h @@ -75,9 +75,6 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface { // `output_dump_file_name` in its VideoConfig, which was used for // CreateFramePreprocessor(...), then video also will be written // into that file. - // TODO(titovartem): Remove method with `peer_name` only parameter. - std::unique_ptr> CreateVideoSink( - absl::string_view peer_name); std::unique_ptr CreateVideoSink( absl::string_view peer_name, const VideoSubscription& subscription, @@ -106,46 +103,6 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface { void Stop(); private: - // Deprecated, to be removed when old API isn't used anymore. - class AnalyzingVideoSink2 final : public rtc::VideoSinkInterface { - public: - explicit AnalyzingVideoSink2(absl::string_view peer_name, - VideoQualityAnalyzerInjectionHelper* helper) - : peer_name_(peer_name), helper_(helper) {} - ~AnalyzingVideoSink2() override = default; - - void OnFrame(const VideoFrame& frame) override { - helper_->OnFrame(peer_name_, frame); - } - - private: - const std::string peer_name_; - VideoQualityAnalyzerInjectionHelper* const helper_; - }; - - struct ReceiverStream { - ReceiverStream(absl::string_view peer_name, absl::string_view stream_label) - : peer_name(peer_name), stream_label(stream_label) {} - - std::string peer_name; - std::string stream_label; - - // Define operators required to use ReceiverStream as std::map key. - bool operator==(const ReceiverStream& o) const { - return peer_name == o.peer_name && stream_label == o.stream_label; - } - bool operator<(const ReceiverStream& o) const { - return (peer_name == o.peer_name) ? stream_label < o.stream_label - : peer_name < o.peer_name; - } - }; - - // Creates a deep copy of the frame and passes it to the video analyzer, while - // passing real frame to the sinks - void OnFrame(absl::string_view peer_name, const VideoFrame& frame); - std::vector>>* - PopulateSinks(const ReceiverStream& receiver_stream); - Clock* const clock_; std::unique_ptr analyzer_; EncodedImageDataInjector* injector_; @@ -154,14 +111,6 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface { std::vector> video_writers_; AnalyzingVideoSinksHelper sinks_helper_; - Mutex mutex_; - int peers_count_ RTC_GUARDED_BY(mutex_); - // Map from stream label to the video config. - std::map known_video_configs_ - RTC_GUARDED_BY(mutex_); - std::map>>> - sinks_ RTC_GUARDED_BY(mutex_); }; } // namespace webrtc_pc_e2e diff --git a/third_party/libwebrtc/test/pc/e2e/media/test_video_capturer_video_track_source.h b/third_party/libwebrtc/test/pc/e2e/media/test_video_capturer_video_track_source.h index 350766bb496a7..70db07b31c3c0 100644 --- a/third_party/libwebrtc/test/pc/e2e/media/test_video_capturer_video_track_source.h +++ b/third_party/libwebrtc/test/pc/e2e/media/test_video_capturer_video_track_source.h @@ -49,13 +49,27 @@ class TestVideoCapturerVideoTrackSource : public test::TestVideoTrackSource { void Stop() override { SetState(kMuted); } + int GetFrameWidth() const override { + return video_capturer_->GetFrameWidth(); + } + + int GetFrameHeight() const override { + return video_capturer_->GetFrameHeight(); + } + bool is_screencast() const override { RTC_DCHECK_RUN_ON(&sequence_checker_); return is_screencast_; } - void SetDisableAdaptation(bool disable_adaptation) { - video_capturer_->SetDisableAdaptation(disable_adaptation); + void SetEnableAdaptation(bool enable_adaptation) { + video_capturer_->SetEnableAdaptation(enable_adaptation); + } + + void OnOutputFormatRequest(int width, + int height, + const absl::optional& max_fps) override { + video_capturer_->OnOutputFormatRequest(width, height, max_fps); } void SetScreencast(bool is_screencast) override { diff --git a/third_party/libwebrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/third_party/libwebrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc index 0e7993e5be86b..8c19172391fbb 100644 --- a/third_party/libwebrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc +++ b/third_party/libwebrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc @@ -138,7 +138,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); audio.sampling_frequency_in_hz = 48000; @@ -160,7 +159,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) { AudioConfig audio; audio.stream_label = "charlie-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_bob_source", "wav"); charlie->SetAudioConfig(std::move(audio)); @@ -211,7 +209,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); audio.sampling_frequency_in_hz = 48000; @@ -231,7 +228,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, AudioConfig audio; audio.stream_label = "charlie-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_bob_source", "wav"); charlie->SetAudioConfig(std::move(audio)); @@ -262,7 +258,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, SmokeH264) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); audio.sampling_frequency_in_hz = 48000; @@ -281,7 +276,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, SmokeH264) { AudioConfig audio; audio.stream_label = "charlie-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_bob_source", "wav"); charlie->SetAudioConfig(std::move(audio)); @@ -413,7 +407,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Echo) { AddPeer(network_links.first, [](PeerConfigurer* alice) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); audio.sampling_frequency_in_hz = 48000; @@ -422,7 +415,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Echo) { AddPeer(network_links.second, [](PeerConfigurer* bob) { AudioConfig audio; audio.stream_label = "bob-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_bob_source", "wav"); bob->SetAudioConfig(std::move(audio)); @@ -450,7 +442,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Simulcast) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); alice->SetAudioConfig(std::move(audio)); @@ -478,7 +469,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Svc) { alice->AddVideoConfig(std::move(simulcast)); AudioConfig audio("alice-audio"); - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); alice->SetAudioConfig(std::move(audio)); @@ -515,7 +505,6 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_HighBitrate) { AudioConfig audio; audio.stream_label = "alice-audio"; - audio.mode = AudioConfig::Mode::kFile; audio.input_file_name = test::ResourcePath("pc_quality_smoke_test_alice_source", "wav"); audio.sampling_frequency_in_hz = 48000; diff --git a/third_party/libwebrtc/test/peer_scenario/BUILD.gn b/third_party/libwebrtc/test/peer_scenario/BUILD.gn index 00492a18a9f3f..18f81a56e6e9b 100644 --- a/third_party/libwebrtc/test/peer_scenario/BUILD.gn +++ b/third_party/libwebrtc/test/peer_scenario/BUILD.gn @@ -22,10 +22,11 @@ if (rtc_include_tests) { "signaling_route.h", ] deps = [ + "..:create_frame_generator_capturer", "..:fake_video_codecs", "..:fileutils", + "..:frame_generator_capturer", "..:test_support", - "../:video_test_common", "../../api:candidate", "../../api:create_time_controller", "../../api:libjingle_peerconnection_api", @@ -37,12 +38,20 @@ if (rtc_include_tests) { "../../api/rtc_event_log:rtc_event_log_factory", "../../api/task_queue:default_task_queue_factory", "../../api/transport:field_trial_based_config", - "../../api/video_codecs:builtin_video_decoder_factory", - "../../api/video_codecs:builtin_video_encoder_factory", + "../../api/video_codecs:video_decoder_factory_template", + "../../api/video_codecs:video_decoder_factory_template_dav1d_adapter", + "../../api/video_codecs:video_decoder_factory_template_libvpx_vp8_adapter", + "../../api/video_codecs:video_decoder_factory_template_libvpx_vp9_adapter", + "../../api/video_codecs:video_decoder_factory_template_open_h264_adapter", + "../../api/video_codecs:video_encoder_factory_template", + "../../api/video_codecs:video_encoder_factory_template_libaom_av1_adapter", + "../../api/video_codecs:video_encoder_factory_template_libvpx_vp8_adapter", + "../../api/video_codecs:video_encoder_factory_template_libvpx_vp9_adapter", + "../../api/video_codecs:video_encoder_factory_template_open_h264_adapter", "../../media:rtc_audio_video", "../../media:rtc_media_base", "../../media:rtp_utils", - "../../modules/audio_device:audio_device_impl", + "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", "../../p2p:rtc_p2p", "../../pc:channel", diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc index 907bac3c51a24..3947dbd877916 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.cc @@ -20,11 +20,20 @@ #include "api/task_queue/default_task_queue_factory.h" #include "api/test/create_time_controller.h" #include "api/transport/field_trial_based_config.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/engine/webrtc_media_engine.h" #include "modules/audio_device/include/test_audio_device.h" #include "p2p/client/basic_port_allocator.h" +#include "test/create_frame_generator_capturer.h" #include "test/fake_decoder.h" #include "test/fake_vp8_encoder.h" #include "test/frame_generator_capturer.h" @@ -263,8 +272,14 @@ PeerScenarioClient::PeerScenarioClient( media_deps.video_decoder_factory = std::make_unique(); } else { - media_deps.video_encoder_factory = CreateBuiltinVideoEncoderFactory(); - media_deps.video_decoder_factory = CreateBuiltinVideoDecoderFactory(); + media_deps.video_encoder_factory = + std::make_unique>(); + media_deps.video_decoder_factory = + std::make_unique>(); } media_deps.audio_encoder_factory = CreateBuiltinAudioEncoderFactory(); media_deps.audio_decoder_factory = CreateBuiltinAudioDecoderFactory(); @@ -317,8 +332,8 @@ PeerScenarioClient::VideoSendTrack PeerScenarioClient::CreateVideo( VideoSendTrackConfig config) { RTC_DCHECK_RUN_ON(signaling_thread_); VideoSendTrack res; - auto capturer = FrameGeneratorCapturer::Create(clock(), *task_queue_factory_, - config.generator); + auto capturer = CreateFrameGeneratorCapturer(clock(), *task_queue_factory_, + config.generator); res.capturer = capturer.get(); capturer->Init(); res.source = rtc::make_ref_counted( diff --git a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h index ab6aac9cf8a6d..e863757759178 100644 --- a/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h +++ b/third_party/libwebrtc/test/peer_scenario/peer_scenario_client.h @@ -22,6 +22,7 @@ #include "api/test/network_emulation_manager.h" #include "api/test/time_controller.h" #include "pc/test/frame_generator_capturer_video_track_source.h" +#include "test/create_frame_generator_capturer.h" #include "test/logging/log_writer.h" namespace webrtc { diff --git a/third_party/libwebrtc/test/peer_scenario/tests/BUILD.gn b/third_party/libwebrtc/test/peer_scenario/tests/BUILD.gn index ba6ec20e84811..fb2948922a11d 100644 --- a/third_party/libwebrtc/test/peer_scenario/tests/BUILD.gn +++ b/third_party/libwebrtc/test/peer_scenario/tests/BUILD.gn @@ -12,6 +12,7 @@ if (rtc_include_tests) { rtc_library("tests") { testonly = true sources = [ + "bwe_ramp_up_test.cc", "peer_scenario_quality_test.cc", "remote_estimate_test.cc", "unsignaled_stream_test.cc", @@ -20,10 +21,14 @@ if (rtc_include_tests) { "..:peer_scenario", "../../:field_trial", "../../:test_support", + "../../../api:rtc_stats_api", + "../../../api/units:data_rate", + "../../../api/units:time_delta", "../../../media:rtc_media_base", "../../../media:stream_params", "../../../modules/rtp_rtcp:rtp_rtcp_format", "../../../pc:media_session", + "../../../pc:pc_test_utils", "../../../pc:session_description", ] } diff --git a/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc new file mode 100644 index 0000000000000..6f3d597390f83 --- /dev/null +++ b/third_party/libwebrtc/test/peer_scenario/tests/bwe_ramp_up_test.cc @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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/rtcstats_objects.h" +#include "api/units/data_rate.h" +#include "api/units/time_delta.h" +#include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtp_util.h" +#include "pc/media_session.h" +#include "pc/test/mock_peer_connection_observers.h" +#include "test/gmock.h" +#include "test/gtest.h" +#include "test/peer_scenario/peer_scenario.h" +#include "test/peer_scenario/peer_scenario_client.h" + +namespace webrtc { +namespace test { + +using ::testing::SizeIs; + +rtc::scoped_refptr GetStatsAndProcess( + PeerScenario& s, + PeerScenarioClient* client) { + auto stats_collector = + rtc::make_ref_counted(); + client->pc()->GetStats(stats_collector.get()); + s.ProcessMessages(TimeDelta::Millis(0)); + RTC_CHECK(stats_collector->called()); + return stats_collector->report(); +} + +DataRate GetAvailableSendBitrate( + const rtc::scoped_refptr& report) { + auto stats = report->GetStatsOfType(); + if (stats.empty()) { + return DataRate::Zero(); + } + return DataRate::BitsPerSec(*stats[0]->available_outgoing_bitrate); +} + +// Test that caller BWE can rampup even if callee can not demux incoming RTP +// packets. +TEST(BweRampupTest, RampUpWithUndemuxableRtpPackets) { + PeerScenario s(*test_info_); + + PeerScenarioClient::Config config = PeerScenarioClient::Config(); + config.disable_encryption = true; + PeerScenarioClient* caller = s.CreateClient(config); + PeerScenarioClient* callee = s.CreateClient(config); + + auto send_node = s.net()->NodeBuilder().Build().node; + auto ret_node = s.net()->NodeBuilder().Build().node; + + s.net()->CreateRoute(caller->endpoint(), {send_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {ret_node}, caller->endpoint()); + + auto signaling = s.ConnectSignaling(caller, callee, {send_node}, {ret_node}); + PeerScenarioClient::VideoSendTrackConfig video_conf; + video_conf.generator.squares_video->framerate = 15; + + PeerScenarioClient::VideoSendTrack track = + caller->CreateVideo("VIDEO", video_conf); + + signaling.StartIceSignaling(); + + std::atomic offer_exchange_done(false); + signaling.NegotiateSdp( + [&](SessionDescriptionInterface* offer) { + RtpHeaderExtensionMap extension_map( + cricket::GetFirstVideoContentDescription(offer->description()) + ->rtp_header_extensions()); + ASSERT_TRUE(extension_map.IsRegistered(kRtpExtensionMid)); + const std::string video_mid = + cricket::GetFirstVideoContent(offer->description())->mid(); + send_node->router()->SetFilter([extension_map, video_mid, &send_node]( + const EmulatedIpPacket& packet) { + if (IsRtpPacket(packet.data)) { + // Replace Mid with another. This should lead to that packets + // can not be demuxed by the callee, but BWE should still + // function. + RtpPacket parsed_packet; + parsed_packet.IdentifyExtensions(extension_map); + EXPECT_TRUE(parsed_packet.Parse(packet.data)); + std::string mid; + if (parsed_packet.GetExtension(&mid)) { + if (mid == video_mid) { + parsed_packet.SetExtension("x"); + EmulatedIpPacket updated_packet(packet.from, packet.to, + parsed_packet.Buffer(), + packet.arrival_time); + send_node->OnPacketReceived(std::move(updated_packet)); + return false; + } + } + } + return true; + }); + }, + [&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation and the packet filter to be setup. + s.WaitAndProcess(&offer_exchange_done); + + DataRate initial_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + s.ProcessMessages(TimeDelta::Seconds(2)); + + auto callee_inbound_stats = + GetStatsAndProcess(s, callee)->GetStatsOfType(); + ASSERT_THAT(callee_inbound_stats, SizeIs(1)); + ASSERT_EQ(*callee_inbound_stats[0]->frames_received, 0); + + DataRate final_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + // Ensure BWE has increased from the initial BWE. BWE will not increase unless + // RTCP feedback is recevied. The increase is just an arbitrary value to + // ensure BWE has increased beyond noise levels. + EXPECT_GT(final_bwe, initial_bwe + DataRate::KilobitsPerSec(345)); +} +} // namespace test +} // namespace webrtc diff --git a/third_party/libwebrtc/test/scenario/BUILD.gn b/third_party/libwebrtc/test/scenario/BUILD.gn index 077d1ae11f26a..c3b8847fd10c3 100644 --- a/third_party/libwebrtc/test/scenario/BUILD.gn +++ b/third_party/libwebrtc/test/scenario/BUILD.gn @@ -69,6 +69,9 @@ if (rtc_include_tests && !build_with_chromium) { ] deps = [ ":column_printer", + "..:frame_generator_capturer", + "..:test_video_capturer", + "..:video_test_constants", "../:fake_video_codecs", "../:fileutils", "../:test_common", @@ -113,8 +116,8 @@ if (rtc_include_tests && !build_with_chromium) { "../../media:rtc_internal_video_codecs", "../../media:rtc_media_base", "../../modules/audio_device", - "../../modules/audio_device:audio_device_impl", "../../modules/audio_device:mock_audio_device", + "../../modules/audio_device:test_audio_device_module", "../../modules/audio_mixer:audio_mixer_impl", "../../modules/audio_processing", "../../modules/congestion_controller/goog_cc:test_goog_cc_printer", diff --git a/third_party/libwebrtc/test/scenario/audio_stream.cc b/third_party/libwebrtc/test/scenario/audio_stream.cc index e134e4b377f88..7715555e23b9f 100644 --- a/third_party/libwebrtc/test/scenario/audio_stream.cc +++ b/third_party/libwebrtc/test/scenario/audio_stream.cc @@ -11,6 +11,7 @@ #include "absl/memory/memory.h" #include "test/call_test.h" +#include "test/video_test_constants.h" #if WEBRTC_ENABLE_PROTOBUF RTC_PUSH_IGNORING_WUNDEF() @@ -103,7 +104,8 @@ SendAudioStream::SendAudioStream( // stereo, but the actual channel count used is based on the "stereo" // parameter. send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec( - CallTest::kAudioSendPayloadType, {"opus", 48000, 2, sdp_params}); + VideoTestConstants::kAudioSendPayloadType, + {"opus", 48000, 2, sdp_params}); RTC_DCHECK_LE(config.source.channels, 2); send_config.encoder_factory = encoder_factory; @@ -190,7 +192,7 @@ ReceiveAudioStream::ReceiveAudioStream( receiver->ssrc_media_types_[recv_config.rtp.remote_ssrc] = MediaType::AUDIO; recv_config.decoder_factory = decoder_factory; recv_config.decoder_map = { - {CallTest::kAudioSendPayloadType, {"opus", 48000, 2}}}; + {VideoTestConstants::kAudioSendPayloadType, {"opus", 48000, 2}}}; recv_config.sync_group = config.render.sync_group; receiver_->SendTask([&] { receive_stream_ = receiver_->call_->CreateAudioReceiveStream(recv_config); diff --git a/third_party/libwebrtc/test/scenario/call_client.cc b/third_party/libwebrtc/test/scenario/call_client.cc index c80f58eeeb63d..d2019aebc79e9 100644 --- a/third_party/libwebrtc/test/scenario/call_client.cc +++ b/third_party/libwebrtc/test/scenario/call_client.cc @@ -19,6 +19,7 @@ #include "api/transport/network_types.h" #include "call/call.h" #include "call/rtp_transport_controller_send_factory.h" +#include "modules/audio_device/include/test_audio_device.h" #include "modules/audio_mixer/audio_mixer_impl.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" diff --git a/third_party/libwebrtc/test/scenario/call_client.h b/third_party/libwebrtc/test/scenario/call_client.h index 5d62fc75e7287..3717a7e7961dd 100644 --- a/third_party/libwebrtc/test/scenario/call_client.h +++ b/third_party/libwebrtc/test/scenario/call_client.h @@ -22,7 +22,7 @@ #include "api/test/time_controller.h" #include "api/units/data_rate.h" #include "call/call.h" -#include "modules/audio_device/include/test_audio_device.h" +#include "modules/audio_device/include/audio_device.h" #include "modules/congestion_controller/goog_cc/test/goog_cc_printer.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "rtc_base/task_queue_for_test.h" @@ -96,7 +96,7 @@ class LoggingNetworkControllerFactory struct CallClientFakeAudio { rtc::scoped_refptr apm; - rtc::scoped_refptr fake_audio_device; + rtc::scoped_refptr fake_audio_device; rtc::scoped_refptr audio_state; }; // CallClient represents a participant in a call scenario. It is created by the diff --git a/third_party/libwebrtc/test/scenario/scenario.cc b/third_party/libwebrtc/test/scenario/scenario.cc index 93377120a1ca5..98f59e6c7dba0 100644 --- a/third_party/libwebrtc/test/scenario/scenario.cc +++ b/third_party/libwebrtc/test/scenario/scenario.cc @@ -80,7 +80,7 @@ Scenario::~Scenario() { if (start_time_.IsFinite()) Stop(); for (auto& call_client : clients_) { - call_client->transport_->Disconnect(); + call_client->SendTask([&] { call_client->transport_->Disconnect(); }); call_client->UnBind(); } } diff --git a/third_party/libwebrtc/test/scenario/video_stream.cc b/third_party/libwebrtc/test/scenario/video_stream.cc index 3879ec86817c6..937ad4f29b20e 100644 --- a/third_party/libwebrtc/test/scenario/video_stream.cc +++ b/third_party/libwebrtc/test/scenario/video_stream.cc @@ -27,6 +27,7 @@ #include "test/fake_encoder.h" #include "test/scenario/hardware_codecs.h" #include "test/testsupport/file_utils.h" +#include "test/video_test_constants.h" #include "video/config/encoder_stream_factory.h" namespace webrtc { @@ -43,13 +44,13 @@ constexpr int kDefaultMaxQp = cricket::WebRtcVideoChannel::kDefaultQpMax; uint8_t CodecTypeToPayloadType(VideoCodecType codec_type) { switch (codec_type) { case VideoCodecType::kVideoCodecGeneric: - return CallTest::kFakeVideoSendPayloadType; + return VideoTestConstants::kFakeVideoSendPayloadType; case VideoCodecType::kVideoCodecVP8: - return CallTest::kPayloadTypeVP8; + return VideoTestConstants::kPayloadTypeVP8; case VideoCodecType::kVideoCodecVP9: - return CallTest::kPayloadTypeVP9; + return VideoTestConstants::kPayloadTypeVP9; case VideoCodecType::kVideoCodecH264: - return CallTest::kPayloadTypeH264; + return VideoTestConstants::kPayloadTypeH264; default: RTC_DCHECK_NOTREACHED(); } @@ -108,18 +109,22 @@ VideoSendStream::Config CreateVideoSendStreamConfig( send_config.rtp.extensions = GetVideoRtpExtensions(config); if (config.stream.use_rtx) { - send_config.rtp.rtx.payload_type = CallTest::kSendRtxPayloadType; + send_config.rtp.rtx.payload_type = VideoTestConstants::kSendRtxPayloadType; send_config.rtp.rtx.ssrcs = rtx_ssrcs; } if (config.stream.use_flexfec) { - send_config.rtp.flexfec.payload_type = CallTest::kFlexfecPayloadType; - send_config.rtp.flexfec.ssrc = CallTest::kFlexfecSendSsrc; + send_config.rtp.flexfec.payload_type = + VideoTestConstants::kFlexfecPayloadType; + send_config.rtp.flexfec.ssrc = VideoTestConstants::kFlexfecSendSsrc; send_config.rtp.flexfec.protected_media_ssrcs = ssrcs; } if (config.stream.use_ulpfec) { - send_config.rtp.ulpfec.red_payload_type = CallTest::kRedPayloadType; - send_config.rtp.ulpfec.ulpfec_payload_type = CallTest::kUlpfecPayloadType; - send_config.rtp.ulpfec.red_rtx_payload_type = CallTest::kRtxRedPayloadType; + send_config.rtp.ulpfec.red_payload_type = + VideoTestConstants::kRedPayloadType; + send_config.rtp.ulpfec.ulpfec_payload_type = + VideoTestConstants::kUlpfecPayloadType; + send_config.rtp.ulpfec.red_rtx_payload_type = + VideoTestConstants::kRtxRedPayloadType; } return send_config; } @@ -323,14 +328,16 @@ VideoReceiveStreamInterface::Config CreateVideoReceiveStreamConfig( recv.renderer = renderer; if (config.stream.use_rtx) { recv.rtp.rtx_ssrc = rtx_ssrc; - recv.rtp.rtx_associated_payload_types[CallTest::kSendRtxPayloadType] = + recv.rtp + .rtx_associated_payload_types[VideoTestConstants::kSendRtxPayloadType] = CodecTypeToPayloadType(config.encoder.codec); } if (config.stream.use_ulpfec) { - recv.rtp.red_payload_type = CallTest::kRedPayloadType; - recv.rtp.ulpfec_payload_type = CallTest::kUlpfecPayloadType; - recv.rtp.rtx_associated_payload_types[CallTest::kRtxRedPayloadType] = - CallTest::kRedPayloadType; + recv.rtp.red_payload_type = VideoTestConstants::kRedPayloadType; + recv.rtp.ulpfec_payload_type = VideoTestConstants::kUlpfecPayloadType; + recv.rtp + .rtx_associated_payload_types[VideoTestConstants::kRtxRedPayloadType] = + VideoTestConstants::kRedPayloadType; } recv.sync_group = config.render.sync_group; return recv; @@ -564,8 +571,8 @@ ReceiveVideoStream::ReceiveVideoStream(CallClient* receiver, if (config.stream.use_flexfec) { RTC_DCHECK(num_streams == 1); FlexfecReceiveStream::Config flexfec(feedback_transport); - flexfec.payload_type = CallTest::kFlexfecPayloadType; - flexfec.rtp.remote_ssrc = CallTest::kFlexfecSendSsrc; + flexfec.payload_type = VideoTestConstants::kFlexfecPayloadType; + flexfec.rtp.remote_ssrc = VideoTestConstants::kFlexfecSendSsrc; flexfec.protected_media_ssrcs = send_stream->rtx_ssrcs_; flexfec.rtp.local_ssrc = recv_config.rtp.local_ssrc; receiver_->ssrc_media_types_[flexfec.rtp.remote_ssrc] = MediaType::VIDEO; diff --git a/third_party/libwebrtc/test/test_video_capturer.cc b/third_party/libwebrtc/test/test_video_capturer.cc index b55eefcb2fc50..3098731eb3b08 100644 --- a/third_party/libwebrtc/test/test_video_capturer.cc +++ b/third_party/libwebrtc/test/test_video_capturer.cc @@ -19,6 +19,7 @@ namespace webrtc { namespace test { + TestVideoCapturer::~TestVideoCapturer() = default; void TestVideoCapturer::OnOutputFormatRequest( @@ -40,12 +41,12 @@ void TestVideoCapturer::OnFrame(const VideoFrame& original_frame) { VideoFrame frame = MaybePreprocess(original_frame); - bool disable_adaptation; + bool enable_adaptation; { MutexLock lock(&lock_); - disable_adaptation = disable_adaptation_; + enable_adaptation = enable_adaptation_; } - if (disable_adaptation) { + if (enable_adaptation) { broadcaster_.OnFrame(frame); } diff --git a/third_party/libwebrtc/test/test_video_capturer.h b/third_party/libwebrtc/test/test_video_capturer.h index 3fc03f07eb031..48b7f7a7f84d4 100644 --- a/third_party/libwebrtc/test/test_video_capturer.h +++ b/third_party/libwebrtc/test/test_video_capturer.h @@ -41,14 +41,17 @@ class TestVideoCapturer : public rtc::VideoSourceInterface { MutexLock lock(&lock_); preprocessor_ = std::move(preprocessor); } - void SetDisableAdaptation(bool disable_adaptation) { + void SetEnableAdaptation(bool enable_adaptation) { MutexLock lock(&lock_); - disable_adaptation_ = disable_adaptation; + enable_adaptation_ = enable_adaptation; } void OnOutputFormatRequest(int width, int height, const absl::optional& max_fps); + virtual int GetFrameWidth() const = 0; + virtual int GetFrameHeight() const = 0; + protected: void OnFrame(const VideoFrame& frame); rtc::VideoSinkWants GetSinkWants(); @@ -59,7 +62,7 @@ class TestVideoCapturer : public rtc::VideoSourceInterface { Mutex lock_; std::unique_ptr preprocessor_ RTC_GUARDED_BY(lock_); - bool disable_adaptation_ RTC_GUARDED_BY(lock_) = false; + bool enable_adaptation_ RTC_GUARDED_BY(lock_) = false; rtc::VideoBroadcaster broadcaster_; cricket::VideoAdapter video_adapter_; }; diff --git a/third_party/libwebrtc/test/vcm_capturer.cc b/third_party/libwebrtc/test/vcm_capturer.cc index e02fc722b28d8..620c1c02f3ee6 100644 --- a/third_party/libwebrtc/test/vcm_capturer.cc +++ b/third_party/libwebrtc/test/vcm_capturer.cc @@ -27,6 +27,8 @@ bool VcmCapturer::Init(size_t width, size_t height, size_t target_fps, size_t capture_device_index) { + width_ = width; + height_ = height; std::unique_ptr device_info( VideoCaptureFactory::CreateDeviceInfo()); diff --git a/third_party/libwebrtc/test/vcm_capturer.h b/third_party/libwebrtc/test/vcm_capturer.h index 5418dc9596261..da2b948fe0d14 100644 --- a/third_party/libwebrtc/test/vcm_capturer.h +++ b/third_party/libwebrtc/test/vcm_capturer.h @@ -31,6 +31,9 @@ class VcmCapturer : public TestVideoCapturer, void OnFrame(const VideoFrame& frame) override; + int GetFrameWidth() const override { return static_cast(width_); } + int GetFrameHeight() const override { return static_cast(height_); } + private: VcmCapturer(); bool Init(size_t width, @@ -39,6 +42,8 @@ class VcmCapturer : public TestVideoCapturer, size_t capture_device_index); void Destroy(); + size_t width_; + size_t height_; rtc::scoped_refptr vcm_; VideoCaptureCapability capability_; }; diff --git a/third_party/libwebrtc/test/video_test_constants.h b/third_party/libwebrtc/test/video_test_constants.h new file mode 100644 index 0000000000000..732d4f0056c9e --- /dev/null +++ b/third_party/libwebrtc/test/video_test_constants.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 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 TEST_VIDEO_TEST_CONSTANTS_H_ +#define TEST_VIDEO_TEST_CONSTANTS_H_ + +#include + +#include "api/units/time_delta.h" + +namespace webrtc { +namespace test { + +class VideoTestConstants { + public: + static constexpr size_t kNumSsrcs = 6; + static constexpr int kNumSimulcastStreams = 3; + static constexpr int kDefaultWidth = 320; + static constexpr int kDefaultHeight = 180; + static constexpr int kDefaultFramerate = 30; + static constexpr TimeDelta kDefaultTimeout = TimeDelta::Seconds(30); + static constexpr TimeDelta kLongTimeout = TimeDelta::Seconds(120); + enum classPayloadTypes : uint8_t { + kSendRtxPayloadType = 98, + kRtxRedPayloadType = 99, + kVideoSendPayloadType = 100, + kAudioSendPayloadType = 103, + kRedPayloadType = 118, + kUlpfecPayloadType = 119, + kFlexfecPayloadType = 120, + kPayloadTypeH264 = 122, + kPayloadTypeVP8 = 123, + kPayloadTypeVP9 = 124, + kPayloadTypeGeneric = 125, + kFakeVideoSendPayloadType = 126, + }; + static constexpr uint32_t kSendRtxSsrcs[kNumSsrcs] = { + 0xBADCAFD, 0xBADCAFE, 0xBADCAFF, 0xBADCB00, 0xBADCB01, 0xBADCB02}; + static constexpr uint32_t kVideoSendSsrcs[kNumSsrcs] = { + 0xC0FFED, 0xC0FFEE, 0xC0FFEF, 0xC0FFF0, 0xC0FFF1, 0xC0FFF2}; + static constexpr uint32_t kAudioSendSsrc = 0xDEADBEEF; + static constexpr uint32_t kFlexfecSendSsrc = 0xBADBEEF; + static constexpr uint32_t kReceiverLocalVideoSsrc = 0x123456; + static constexpr uint32_t kReceiverLocalAudioSsrc = 0x1234567; + static constexpr int kNackRtpHistoryMs = 1000; + + private: + VideoTestConstants() = default; +}; + +} // namespace test +} // namespace webrtc + +#endif // TEST_VIDEO_TEST_CONSTANTS_H_ diff --git a/third_party/libwebrtc/video/BUILD.gn b/third_party/libwebrtc/video/BUILD.gn index 3139fc8710ddc..ea8bbdfbb2ad3 100644 --- a/third_party/libwebrtc/video/BUILD.gn +++ b/third_party/libwebrtc/video/BUILD.gn @@ -124,7 +124,6 @@ rtc_library("video") { "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", "../modules/rtp_rtcp:rtp_video_header", - "../modules/utility:utility", "../modules/video_coding", "../modules/video_coding:nack_requester", "../modules/video_coding:packet_buffer", @@ -346,6 +345,7 @@ rtc_library("decode_synchronizer") { "../api/units:time_delta", "../api/units:timestamp", "../rtc_base:checks", + "../rtc_base:event_tracer", "../rtc_base:logging", "../rtc_base:macromagic", ] @@ -539,6 +539,7 @@ if (rtc_include_tests) { "../test:test_support", "../test:test_support_test_artifacts", "../test:video_test_common", + "../test:video_test_constants", "../test:video_test_support", "config:streams_config", ] @@ -904,6 +905,7 @@ if (rtc_include_tests) { "../test:fake_video_codecs", "../test:field_trial", "../test:fileutils", + "../test:frame_generator_capturer", "../test:frame_utils", "../test:mock_frame_transformer", "../test:mock_transport", @@ -914,6 +916,7 @@ if (rtc_include_tests) { "../test:test_common", "../test:test_support", "../test:video_test_common", + "../test:video_test_constants", "../test/time_controller", "adaptation:video_adaptation", "config:encoder_config", diff --git a/third_party/libwebrtc/video/cpu_scaling_tests.cc b/third_party/libwebrtc/video/cpu_scaling_tests.cc index b9f3a45e94bed..79473721b71bc 100644 --- a/third_party/libwebrtc/video/cpu_scaling_tests.cc +++ b/third_party/libwebrtc/video/cpu_scaling_tests.cc @@ -23,6 +23,7 @@ #include "test/field_trial.h" #include "test/frame_generator_capturer.h" #include "test/gtest.h" +#include "test/video_test_constants.h" #include "video/config/video_encoder_config.h" namespace webrtc { @@ -55,7 +56,9 @@ void CpuOveruseTest::RunTestAndCheckForAdaptation( public: OveruseObserver(const DegradationPreference& degradation_preference, bool expect_adaptation) - : SendTest(expect_adaptation ? kLongTimeout : kDefaultTimeout), + : SendTest(expect_adaptation + ? test::VideoTestConstants::kLongTimeout + : test::VideoTestConstants::kDefaultTimeout), degradation_preference_(degradation_preference), expect_adaptation_(expect_adaptation) {} diff --git a/third_party/libwebrtc/video/decode_synchronizer.cc b/third_party/libwebrtc/video/decode_synchronizer.cc index e676acfcf0d27..2b9a658426d77 100644 --- a/third_party/libwebrtc/video/decode_synchronizer.cc +++ b/third_party/libwebrtc/video/decode_synchronizer.cc @@ -20,6 +20,7 @@ #include "api/units/timestamp.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" +#include "rtc_base/trace_event.h" #include "video/frame_decode_scheduler.h" #include "video/frame_decode_timing.h" @@ -117,6 +118,7 @@ DecodeSynchronizer::~DecodeSynchronizer() { std::unique_ptr DecodeSynchronizer::CreateSynchronizedFrameScheduler() { + TRACE_EVENT0("webrtc", __func__); RTC_DCHECK_RUN_ON(worker_queue_); auto scheduler = std::make_unique(this); auto [it, inserted] = schedulers_.emplace(scheduler.get()); @@ -157,6 +159,7 @@ void DecodeSynchronizer::OnFrameScheduled( void DecodeSynchronizer::RemoveFrameScheduler( SynchronizedFrameDecodeScheduler* scheduler) { + TRACE_EVENT0("webrtc", __func__); RTC_DCHECK_RUN_ON(worker_queue_); RTC_DCHECK(scheduler); auto it = schedulers_.find(scheduler); @@ -177,6 +180,7 @@ void DecodeSynchronizer::ScheduleNextTick() { } void DecodeSynchronizer::OnTick() { + TRACE_EVENT0("webrtc", __func__); RTC_DCHECK_RUN_ON(worker_queue_); expected_next_tick_ = clock_->CurrentTime() + metronome_->TickPeriod(); diff --git a/third_party/libwebrtc/video/encoder_bitrate_adjuster.cc b/third_party/libwebrtc/video/encoder_bitrate_adjuster.cc index 811e0e49dd27b..465d517d2143a 100644 --- a/third_party/libwebrtc/video/encoder_bitrate_adjuster.cc +++ b/third_party/libwebrtc/video/encoder_bitrate_adjuster.cc @@ -47,12 +47,14 @@ EncoderBitrateAdjuster::EncoderBitrateAdjuster(const VideoCodec& codec_settings) : utilize_bandwidth_headroom_(RateControlSettings::ParseFromFieldTrials() .BitrateAdjusterCanUseNetworkHeadroom()), frames_since_layout_change_(0), - min_bitrates_bps_{} { + min_bitrates_bps_{}, + codec_(codec_settings.codecType), + codec_mode_(codec_settings.mode) { // TODO(https://crbug.com/webrtc/14891): If we want to support simulcast of // SVC streams, EncoderBitrateAdjuster needs to be updated to care about both // `simulcastStream` and `spatialLayers` at the same time. if (codec_settings.codecType == VideoCodecType::kVideoCodecVP9 && - codec_settings.IsSinglecastOrAllNonFirstLayersInactive()) { + codec_settings.numberOfSimulcastStreams <= 1) { for (size_t si = 0; si < codec_settings.VP9().numberOfSpatialLayers; ++si) { if (codec_settings.spatialLayers[si].active) { min_bitrates_bps_[si] = @@ -90,7 +92,9 @@ VideoBitrateAllocation EncoderBitrateAdjuster::AdjustRateAllocation( ++active_tls[si]; if (!overshoot_detectors_[si][ti]) { overshoot_detectors_[si][ti] = - std::make_unique(kWindowSizeMs); + std::make_unique( + kWindowSizeMs, codec_, + codec_mode_ == VideoCodecMode::kScreensharing); frames_since_layout_change_ = 0; } } else if (overshoot_detectors_[si][ti]) { diff --git a/third_party/libwebrtc/video/encoder_bitrate_adjuster.h b/third_party/libwebrtc/video/encoder_bitrate_adjuster.h index 6dc3e5534f9cd..6b35186b9844f 100644 --- a/third_party/libwebrtc/video/encoder_bitrate_adjuster.h +++ b/third_party/libwebrtc/video/encoder_bitrate_adjuster.h @@ -73,6 +73,12 @@ class EncoderBitrateAdjuster { // Minimum bitrates allowed, per spatial layer. uint32_t min_bitrates_bps_[kMaxSpatialLayers]; + + // Codec type used for encoding. + VideoCodecType codec_; + + // Codec mode: { kRealtimeVideo, kScreensharing }. + VideoCodecMode codec_mode_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/video/encoder_overshoot_detector.cc b/third_party/libwebrtc/video/encoder_overshoot_detector.cc index 80b2ec12b0ae1..2c4efdb5a6306 100644 --- a/third_party/libwebrtc/video/encoder_overshoot_detector.cc +++ b/third_party/libwebrtc/video/encoder_overshoot_detector.cc @@ -11,6 +11,9 @@ #include "video/encoder_overshoot_detector.h" #include +#include + +#include "system_wrappers/include/metrics.h" namespace webrtc { namespace { @@ -20,7 +23,9 @@ namespace { static constexpr double kMaxMediaUnderrunFrames = 5.0; } // namespace -EncoderOvershootDetector::EncoderOvershootDetector(int64_t window_size_ms) +EncoderOvershootDetector::EncoderOvershootDetector(int64_t window_size_ms, + VideoCodecType codec, + bool is_screenshare) : window_size_ms_(window_size_ms), time_last_update_ms_(-1), sum_network_utilization_factors_(0.0), @@ -28,9 +33,16 @@ EncoderOvershootDetector::EncoderOvershootDetector(int64_t window_size_ms) target_bitrate_(DataRate::Zero()), target_framerate_fps_(0), network_buffer_level_bits_(0), - media_buffer_level_bits_(0) {} + media_buffer_level_bits_(0), + codec_(codec), + is_screenshare_(is_screenshare), + frame_count_(0), + sum_diff_kbps_squared_(0), + sum_overshoot_percent_(0) {} -EncoderOvershootDetector::~EncoderOvershootDetector() = default; +EncoderOvershootDetector::~EncoderOvershootDetector() { + UpdateHistograms(); +} void EncoderOvershootDetector::SetTargetRate(DataRate target_bitrate, double target_framerate_fps, @@ -57,6 +69,7 @@ void EncoderOvershootDetector::OnEncodedFrame(size_t bytes, int64_t time_ms) { // bitrate. LeakBits(time_ms); + const int64_t frame_size_bits = bytes * 8; // Ideal size of a frame given the current rates. const int64_t ideal_frame_size_bits = IdealFrameSizeBits(); if (ideal_frame_size_bits == 0) { @@ -64,14 +77,22 @@ void EncoderOvershootDetector::OnEncodedFrame(size_t bytes, int64_t time_ms) { return; } - const double network_utilization_factor = HandleEncodedFrame( - bytes * 8, ideal_frame_size_bits, time_ms, &network_buffer_level_bits_); - const double media_utilization_factor = HandleEncodedFrame( - bytes * 8, ideal_frame_size_bits, time_ms, &media_buffer_level_bits_); + const double network_utilization_factor = + HandleEncodedFrame(frame_size_bits, ideal_frame_size_bits, time_ms, + &network_buffer_level_bits_); + const double media_utilization_factor = + HandleEncodedFrame(frame_size_bits, ideal_frame_size_bits, time_ms, + &media_buffer_level_bits_); sum_network_utilization_factors_ += network_utilization_factor; sum_media_utilization_factors_ += media_utilization_factor; + // Calculate the bitrate diff in kbps + int64_t diff_kbits = (frame_size_bits - ideal_frame_size_bits) / 1000; + sum_diff_kbps_squared_ += diff_kbits * diff_kbits; + sum_overshoot_percent_ += diff_kbits * 100 * 1000 / ideal_frame_size_bits; + ++frame_count_; + utilization_factors_.emplace_back(network_utilization_factor, media_utilization_factor, time_ms); } @@ -142,6 +163,10 @@ absl::optional EncoderOvershootDetector::GetMediaRateUtilizationFactor( } void EncoderOvershootDetector::Reset() { + UpdateHistograms(); + sum_diff_kbps_squared_ = 0; + frame_count_ = 0; + sum_overshoot_percent_ = 0; time_last_update_ms_ = -1; utilization_factors_.clear(); target_bitrate_ = DataRate::Zero(); @@ -201,4 +226,50 @@ void EncoderOvershootDetector::CullOldUpdates(int64_t time_ms) { } } +void EncoderOvershootDetector::UpdateHistograms() { + if (frame_count_ == 0) + return; + + int64_t bitrate_rmse = std::sqrt(sum_diff_kbps_squared_ / frame_count_); + int64_t average_overshoot_percent = sum_overshoot_percent_ / frame_count_; + const std::string rmse_histogram_prefix = + is_screenshare_ ? "WebRTC.Video.Screenshare.RMSEOfEncodingBitrateInKbps." + : "WebRTC.Video.RMSEOfEncodingBitrateInKbps."; + const std::string overshoot_histogram_prefix = + is_screenshare_ ? "WebRTC.Video.Screenshare.EncodingBitrateOvershoot." + : "WebRTC.Video.EncodingBitrateOvershoot."; + // index = 1 represents screensharing histograms recording. + // index = 0 represents normal video histograms recording. + const int index = is_screenshare_ ? 1 : 0; + switch (codec_) { + case VideoCodecType::kVideoCodecAV1: + RTC_HISTOGRAMS_COUNTS_10000(index, rmse_histogram_prefix + "Av1", + bitrate_rmse); + RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "Av1", + average_overshoot_percent); + break; + case VideoCodecType::kVideoCodecVP9: + RTC_HISTOGRAMS_COUNTS_10000(index, rmse_histogram_prefix + "Vp9", + bitrate_rmse); + RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "Vp9", + average_overshoot_percent); + break; + case VideoCodecType::kVideoCodecVP8: + RTC_HISTOGRAMS_COUNTS_10000(index, rmse_histogram_prefix + "Vp8", + bitrate_rmse); + RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "Vp8", + average_overshoot_percent); + break; + case VideoCodecType::kVideoCodecH264: + RTC_HISTOGRAMS_COUNTS_10000(index, rmse_histogram_prefix + "H264", + bitrate_rmse); + RTC_HISTOGRAMS_COUNTS_10000(index, overshoot_histogram_prefix + "H264", + average_overshoot_percent); + break; + case VideoCodecType::kVideoCodecGeneric: + case VideoCodecType::kVideoCodecMultiplex: + break; + } +} + } // namespace webrtc diff --git a/third_party/libwebrtc/video/encoder_overshoot_detector.h b/third_party/libwebrtc/video/encoder_overshoot_detector.h index 1f8908e54f2d0..12c4bba5db96f 100644 --- a/third_party/libwebrtc/video/encoder_overshoot_detector.h +++ b/third_party/libwebrtc/video/encoder_overshoot_detector.h @@ -15,12 +15,15 @@ #include "absl/types/optional.h" #include "api/units/data_rate.h" +#include "api/video_codecs/video_codec.h" namespace webrtc { class EncoderOvershootDetector { public: - explicit EncoderOvershootDetector(int64_t window_size_ms); + explicit EncoderOvershootDetector(int64_t window_size_ms, + VideoCodecType codec, + bool is_screenshare); ~EncoderOvershootDetector(); void SetTargetRate(DataRate target_bitrate, @@ -64,6 +67,7 @@ class EncoderOvershootDetector { double media_utilization_factor; int64_t update_time_ms; }; + void UpdateHistograms(); std::deque utilization_factors_; double sum_network_utilization_factors_; double sum_media_utilization_factors_; @@ -71,6 +75,11 @@ class EncoderOvershootDetector { double target_framerate_fps_; int64_t network_buffer_level_bits_; int64_t media_buffer_level_bits_; + VideoCodecType codec_; + bool is_screenshare_; + int64_t frame_count_; + int64_t sum_diff_kbps_squared_; + int64_t sum_overshoot_percent_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/video/encoder_overshoot_detector_unittest.cc b/third_party/libwebrtc/video/encoder_overshoot_detector_unittest.cc index a3c44eb013365..bdc2676281e3b 100644 --- a/third_party/libwebrtc/video/encoder_overshoot_detector_unittest.cc +++ b/third_party/libwebrtc/video/encoder_overshoot_detector_unittest.cc @@ -10,23 +10,58 @@ #include "video/encoder_overshoot_detector.h" +#include + #include "api/units/data_rate.h" #include "rtc_base/fake_clock.h" #include "rtc_base/time_utils.h" +#include "system_wrappers/include/metrics.h" #include "test/gtest.h" namespace webrtc { -class EncoderOvershootDetectorTest : public ::testing::Test { +namespace { + +using ::testing::TestWithParam; +using ::testing::ValuesIn; + +static std::string CodecTypeToHistogramSuffix(VideoCodecType codec) { + switch (codec) { + case kVideoCodecVP8: + return "Vp8"; + case kVideoCodecVP9: + return "Vp9"; + case kVideoCodecAV1: + return "Av1"; + case kVideoCodecH264: + return "H264"; + case kVideoCodecGeneric: + return "Generic"; + case kVideoCodecMultiplex: + return "Multiplex"; + } +} + +struct TestParams { + VideoCodecType codec_type; + bool is_screenshare; +}; + +} // namespace + +class EncoderOvershootDetectorTest : public TestWithParam { public: static constexpr int kDefaultBitrateBps = 300000; static constexpr double kDefaultFrameRateFps = 15; EncoderOvershootDetectorTest() - : detector_(kWindowSizeMs), + : detector_(kWindowSizeMs, + GetParam().codec_type, + GetParam().is_screenshare), target_bitrate_(DataRate::BitsPerSec(kDefaultBitrateBps)), target_framerate_fps_(kDefaultFrameRateFps) {} protected: + void SetUp() override { metrics::Reset(); } void RunConstantUtilizationTest(double actual_utilization_factor, double expected_utilization_factor, double allowed_error, @@ -70,7 +105,7 @@ class EncoderOvershootDetectorTest : public ::testing::Test { double target_framerate_fps_; }; -TEST_F(EncoderOvershootDetectorTest, NoUtilizationIfNoRate) { +TEST_P(EncoderOvershootDetectorTest, NoUtilizationIfNoRate) { const int frame_size_bytes = 1000; const int64_t time_interval_ms = 33; detector_.SetTargetRate(target_bitrate_, target_framerate_fps_, @@ -86,26 +121,26 @@ TEST_F(EncoderOvershootDetectorTest, NoUtilizationIfNoRate) { detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis()).has_value()); } -TEST_F(EncoderOvershootDetectorTest, OptimalSize) { +TEST_P(EncoderOvershootDetectorTest, OptimalSize) { // Optimally behaved encoder. // Allow some error margin due to rounding errors, eg due to frame // interval not being an integer. RunConstantUtilizationTest(1.0, 1.0, 0.01, kWindowSizeMs); } -TEST_F(EncoderOvershootDetectorTest, Undershoot) { +TEST_P(EncoderOvershootDetectorTest, Undershoot) { // Undershoot, reported utilization factor should be capped to 1.0 so // that we don't incorrectly boost encoder bitrate during movement. RunConstantUtilizationTest(0.5, 1.0, 0.00, kWindowSizeMs); } -TEST_F(EncoderOvershootDetectorTest, Overshoot) { +TEST_P(EncoderOvershootDetectorTest, Overshoot) { // Overshoot by 20%. // Allow some error margin due to rounding errors. RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs); } -TEST_F(EncoderOvershootDetectorTest, ConstantOvershootVaryingRates) { +TEST_P(EncoderOvershootDetectorTest, ConstantOvershootVaryingRates) { // Overshoot by 20%, but vary framerate and bitrate. // Allow some error margin due to rounding errors. RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs); @@ -115,7 +150,7 @@ TEST_F(EncoderOvershootDetectorTest, ConstantOvershootVaryingRates) { RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs / 2); } -TEST_F(EncoderOvershootDetectorTest, ConstantRateVaryingOvershoot) { +TEST_P(EncoderOvershootDetectorTest, ConstantRateVaryingOvershoot) { // Overshoot by 10%, keep framerate and bitrate constant. // Allow some error margin due to rounding errors. RunConstantUtilizationTest(1.1, 1.1, 0.01, kWindowSizeMs); @@ -127,7 +162,7 @@ TEST_F(EncoderOvershootDetectorTest, ConstantRateVaryingOvershoot) { RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs / 2); } -TEST_F(EncoderOvershootDetectorTest, PartialOvershoot) { +TEST_P(EncoderOvershootDetectorTest, PartialOvershoot) { const int ideal_frame_size_bytes = (target_bitrate_.bps() / target_framerate_fps_) / 8; detector_.SetTargetRate(target_bitrate_, target_framerate_fps_, @@ -163,4 +198,83 @@ TEST_F(EncoderOvershootDetectorTest, PartialOvershoot) { detector_.GetMediaRateUtilizationFactor(rtc::TimeMillis()); EXPECT_NEAR(media_utilization_factor.value_or(-1), 1.00, 0.01); } + +TEST_P(EncoderOvershootDetectorTest, RecordsZeroErrorMetricWithNoOvershoot) { + DataSize ideal_frame_size = + target_bitrate_ / Frequency::Hertz(target_framerate_fps_); + detector_.SetTargetRate(target_bitrate_, target_framerate_fps_, + rtc::TimeMillis()); + detector_.OnEncodedFrame(ideal_frame_size.bytes(), rtc::TimeMillis()); + detector_.Reset(); + + const VideoCodecType codec = GetParam().codec_type; + const bool is_screenshare = GetParam().is_screenshare; + const std::string rmse_histogram_prefix = + is_screenshare ? "WebRTC.Video.Screenshare.RMSEOfEncodingBitrateInKbps." + : "WebRTC.Video.RMSEOfEncodingBitrateInKbps."; + const std::string overshoot_histogram_prefix = + is_screenshare ? "WebRTC.Video.Screenshare.EncodingBitrateOvershoot." + : "WebRTC.Video.EncodingBitrateOvershoot."; + // RMSE and overshoot percent = 0, since we used ideal frame size. + EXPECT_METRIC_EQ(1, metrics::NumSamples(rmse_histogram_prefix + + CodecTypeToHistogramSuffix(codec))); + EXPECT_METRIC_EQ( + 1, metrics::NumEvents( + rmse_histogram_prefix + CodecTypeToHistogramSuffix(codec), 0)); + + EXPECT_METRIC_EQ(1, metrics::NumSamples(overshoot_histogram_prefix + + CodecTypeToHistogramSuffix(codec))); + EXPECT_METRIC_EQ(1, metrics::NumEvents(overshoot_histogram_prefix + + CodecTypeToHistogramSuffix(codec), + 0)); +} + +TEST_P(EncoderOvershootDetectorTest, + RecordScreenshareZeroMetricWithNoOvershoot) { + DataSize ideal_frame_size = + target_bitrate_ / Frequency::Hertz(target_framerate_fps_); + // Use target frame size with 50% overshoot. + DataSize target_frame_size = ideal_frame_size * 3 / 2; + detector_.SetTargetRate(target_bitrate_, target_framerate_fps_, + rtc::TimeMillis()); + detector_.OnEncodedFrame(target_frame_size.bytes(), rtc::TimeMillis()); + detector_.Reset(); + + const VideoCodecType codec = GetParam().codec_type; + const bool is_screenshare = GetParam().is_screenshare; + const std::string rmse_histogram_prefix = + is_screenshare ? "WebRTC.Video.Screenshare.RMSEOfEncodingBitrateInKbps." + : "WebRTC.Video.RMSEOfEncodingBitrateInKbps."; + const std::string overshoot_histogram_prefix = + is_screenshare ? "WebRTC.Video.Screenshare.EncodingBitrateOvershoot." + : "WebRTC.Video.EncodingBitrateOvershoot."; + // Use ideal_frame_size_kbits to represnt ideal_frame_size.bytes()*8/1000, + // then rmse_in_kbps = ideal_frame_size_kbits/2 + // since we use target frame size with 50% overshoot. + int64_t rmse_in_kbps = ideal_frame_size.bytes() * 8 / 1000 / 2; + EXPECT_METRIC_EQ(1, metrics::NumSamples(rmse_histogram_prefix + + CodecTypeToHistogramSuffix(codec))); + EXPECT_METRIC_EQ(1, metrics::NumEvents(rmse_histogram_prefix + + CodecTypeToHistogramSuffix(codec), + rmse_in_kbps)); + // overshoot percent = 50, since we used ideal_frame_size * 3 / 2; + EXPECT_METRIC_EQ(1, metrics::NumSamples(overshoot_histogram_prefix + + CodecTypeToHistogramSuffix(codec))); + EXPECT_METRIC_EQ(1, metrics::NumEvents(overshoot_histogram_prefix + + CodecTypeToHistogramSuffix(codec), + 50)); +} + +INSTANTIATE_TEST_SUITE_P( + PerCodecType, + EncoderOvershootDetectorTest, + ValuesIn({{VideoCodecType::kVideoCodecVP8, false}, + {VideoCodecType::kVideoCodecVP8, true}, + {VideoCodecType::kVideoCodecVP9, false}, + {VideoCodecType::kVideoCodecVP9, true}, + {VideoCodecType::kVideoCodecAV1, false}, + {VideoCodecType::kVideoCodecAV1, true}, + {VideoCodecType::kVideoCodecH264, false}, + {VideoCodecType::kVideoCodecH264, true}})); + } // namespace webrtc diff --git a/third_party/libwebrtc/video/end_to_end_tests/bandwidth_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/bandwidth_tests.cc index d6610a8ec2ad5..1e36f2f6867d5 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/bandwidth_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/bandwidth_tests.cc @@ -29,6 +29,7 @@ #include "test/rtcp_packet_parser.h" #include "test/rtp_rtcp_observer.h" #include "test/video_encoder_proxy_factory.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -46,7 +47,7 @@ class BandwidthEndToEndTest : public test::CallTest { TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) { class RembObserver : public test::EndToEndTest { public: - RembObserver() : EndToEndTest(kDefaultTimeout) {} + RembObserver() : EndToEndTest(test::VideoTestConstants::kDefaultTimeout) {} void ModifyVideoConfigs( VideoSendStream::Config* send_config, @@ -62,10 +63,12 @@ TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) { EXPECT_TRUE(parser.Parse(packet, length)); if (parser.remb()->num_packets() > 0) { - EXPECT_EQ(kReceiverLocalVideoSsrc, parser.remb()->sender_ssrc()); + EXPECT_EQ(test::VideoTestConstants::kReceiverLocalVideoSsrc, + parser.remb()->sender_ssrc()); EXPECT_LT(0U, parser.remb()->bitrate_bps()); EXPECT_EQ(1U, parser.remb()->ssrcs().size()); - EXPECT_EQ(kVideoSendSsrcs[0], parser.remb()->ssrcs()[0]); + EXPECT_EQ(test::VideoTestConstants::kVideoSendSsrcs[0], + parser.remb()->ssrcs()[0]); observation_complete_.Set(); } @@ -84,7 +87,7 @@ TEST_F(BandwidthEndToEndTest, ReceiveStreamSendsRemb) { class BandwidthStatsTest : public test::EndToEndTest { public: BandwidthStatsTest(bool send_side_bwe, TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), sender_call_(nullptr), receiver_call_(nullptr), has_seen_pacer_delay_(false), @@ -191,7 +194,7 @@ TEST_F(BandwidthEndToEndTest, RembWithSendSideBwe) { class BweObserver : public test::EndToEndTest { public: explicit BweObserver(TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), sender_call_(nullptr), clock_(Clock::GetRealTimeClock()), sender_ssrc_(0), @@ -315,7 +318,7 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) { public test::FakeEncoder { public: explicit EncoderRateStatsTest(TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), task_queue_(task_queue), send_stream_(nullptr), @@ -363,7 +366,7 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) { } void WaitForEncoderTargetBitrateMatchStats() { - for (int i = 0; i < kDefaultTimeout.ms(); ++i) { + for (int i = 0; i < test::VideoTestConstants::kDefaultTimeout.ms(); ++i) { VideoSendStream::Stats stats = send_stream_->GetStats(); { MutexLock lock(&mutex_); @@ -379,7 +382,7 @@ TEST_F(BandwidthEndToEndTest, ReportsSetEncoderRates) { } void WaitForStatsReportZeroTargetBitrate() { - for (int i = 0; i < kDefaultTimeout.ms(); ++i) { + for (int i = 0; i < test::VideoTestConstants::kDefaultTimeout.ms(); ++i) { if (send_stream_->GetStats().target_media_bitrate_bps == 0) { return; } diff --git a/third_party/libwebrtc/video/end_to_end_tests/call_operation_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/call_operation_tests.cc index f5b32388b18b7..7a026c3a8f315 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/call_operation_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/call_operation_tests.cc @@ -22,6 +22,7 @@ #include "test/frame_forwarder.h" #include "test/gtest.h" #include "test/null_transport.h" +#include "test/video_test_constants.h" namespace webrtc { @@ -88,7 +89,9 @@ TEST_F(CallOperationEndToEndTest, RendersSingleDelayedFrame) { event_.Set(); } - bool Wait() { return event_.Wait(kDefaultTimeout); } + bool Wait() { + return event_.Wait(test::VideoTestConstants::kDefaultTimeout); + } rtc::Event event_; } renderer; @@ -143,7 +146,9 @@ TEST_F(CallOperationEndToEndTest, TransmitsFirstFrame) { public: void OnFrame(const VideoFrame& video_frame) override { event_.Set(); } - bool Wait() { return event_.Wait(kDefaultTimeout); } + bool Wait() { + return event_.Wait(test::VideoTestConstants::kDefaultTimeout); + } rtc::Event event_; } renderer; @@ -170,7 +175,9 @@ TEST_F(CallOperationEndToEndTest, TransmitsFirstFrame) { Start(); frame_generator = test::CreateSquareFrameGenerator( - kDefaultWidth, kDefaultHeight, absl::nullopt, absl::nullopt); + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight, absl::nullopt, + absl::nullopt); GetVideoSendStream()->SetSource( &frame_forwarder, DegradationPreference::MAINTAIN_FRAMERATE); test::FrameGeneratorInterface::VideoFrameData frame_data = diff --git a/third_party/libwebrtc/video/end_to_end_tests/codec_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/codec_tests.cc index 53ec9f5b173c3..c56e7c5e8bea5 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/codec_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/codec_tests.cc @@ -9,6 +9,7 @@ */ #include + #include "absl/types/optional.h" #include "api/test/video/function_video_encoder_factory.h" #include "api/video/color_space.h" @@ -25,6 +26,7 @@ #include "test/encoder_settings.h" #include "test/field_trial.h" #include "test/gtest.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -53,7 +55,7 @@ class CodecObserver : public test::EndToEndTest, const std::string& payload_name, VideoEncoderFactory* encoder_factory, VideoDecoderFactory* decoder_factory) - : EndToEndTest(4 * CodecEndToEndTest::kDefaultTimeout), + : EndToEndTest(4 * test::VideoTestConstants::kDefaultTimeout), // TODO(hta): This timeout (120 seconds) is excessive. // https://bugs.webrtc.org/6830 no_frames_to_wait_for_(no_frames_to_wait_for), @@ -76,7 +78,8 @@ class CodecObserver : public test::EndToEndTest, encoder_config->codec_type = PayloadStringToCodecType(payload_name_); send_config->encoder_settings.encoder_factory = encoder_factory_; send_config->rtp.payload_name = payload_name_; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; (*receive_configs)[0].renderer = this; (*receive_configs)[0].decoders.resize(1); diff --git a/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc index 2897212e0bf05..ac16a8eb37ec3 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/extended_reports_tests.cc @@ -39,6 +39,7 @@ #include "test/gtest.h" #include "test/rtcp_packet_parser.h" #include "test/rtp_rtcp_observer.h" +#include "test/video_test_constants.h" #include "video/config/video_encoder_config.h" namespace webrtc { @@ -63,7 +64,7 @@ class RtcpXrObserver : public test::EndToEndTest { bool expect_target_bitrate, bool enable_zero_target_bitrate, VideoEncoderConfig::ContentType content_type) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), enable_rrtr_(enable_rrtr), expect_target_bitrate_(expect_target_bitrate), enable_zero_target_bitrate_(enable_zero_target_bitrate), @@ -104,7 +105,7 @@ class RtcpXrObserver : public test::EndToEndTest { test::RtcpPacketParser parser; EXPECT_TRUE(parser.Parse(packet, length)); - if (parser.sender_ssrc() == test::CallTest::kVideoSendSsrcs[1] && + if (parser.sender_ssrc() == test::VideoTestConstants::kVideoSendSsrcs[1] && enable_zero_target_bitrate_) { // Reduce bandwidth restriction to disable second stream after it was // enabled for some time. diff --git a/third_party/libwebrtc/video/end_to_end_tests/fec_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/fec_tests.cc index bf3ad0b22daca..f2ab161a7670d 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/fec_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/fec_tests.cc @@ -26,6 +26,7 @@ #include "test/gmock.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" using ::testing::Contains; using ::testing::Not; @@ -53,7 +54,7 @@ TEST_F(FecEndToEndTest, ReceivesUlpfec) { public rtc::VideoSinkInterface { public: UlpfecRenderObserver() - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), encoder_factory_([]() { return VP8Encoder::Create(); }), random_(0xcafef00d1), num_packets_sent_(0) {} @@ -64,31 +65,38 @@ TEST_F(FecEndToEndTest, ReceivesUlpfec) { RtpPacket rtp_packet; EXPECT_TRUE(rtp_packet.Parse(packet, length)); - EXPECT_TRUE(rtp_packet.PayloadType() == kVideoSendPayloadType || - rtp_packet.PayloadType() == kRedPayloadType) + EXPECT_TRUE(rtp_packet.PayloadType() == + test::VideoTestConstants::kVideoSendPayloadType || + rtp_packet.PayloadType() == + test::VideoTestConstants::kRedPayloadType) << "Unknown payload type received."; - EXPECT_EQ(kVideoSendSsrcs[0], rtp_packet.Ssrc()) + EXPECT_EQ(test::VideoTestConstants::kVideoSendSsrcs[0], rtp_packet.Ssrc()) << "Unknown SSRC received."; // Parse RED header. int encapsulated_payload_type = -1; - if (rtp_packet.PayloadType() == kRedPayloadType) { + if (rtp_packet.PayloadType() == + test::VideoTestConstants::kRedPayloadType) { encapsulated_payload_type = rtp_packet.payload()[0]; - EXPECT_TRUE(encapsulated_payload_type == kVideoSendPayloadType || - encapsulated_payload_type == kUlpfecPayloadType) + EXPECT_TRUE(encapsulated_payload_type == + test::VideoTestConstants::kVideoSendPayloadType || + encapsulated_payload_type == + test::VideoTestConstants::kUlpfecPayloadType) << "Unknown encapsulated payload type received."; } // To minimize test flakiness, always let ULPFEC packets through. - if (encapsulated_payload_type == kUlpfecPayloadType) { + if (encapsulated_payload_type == + test::VideoTestConstants::kUlpfecPayloadType) { return SEND_PACKET; } // Simulate 5% video packet loss after rampup period. Record the // corresponding timestamps that were dropped. if (num_packets_sent_++ > 100 && random_.Rand(1, 100) <= 5) { - if (encapsulated_payload_type == kVideoSendPayloadType) { + if (encapsulated_payload_type == + test::VideoTestConstants::kVideoSendPayloadType) { dropped_sequence_numbers_.insert(rtp_packet.SequenceNumber()); dropped_timestamps_.insert(rtp_packet.Timestamp()); } @@ -116,7 +124,8 @@ TEST_F(FecEndToEndTest, ReceivesUlpfec) { // in the packetization headers. send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = "VP8"; - send_config->rtp.payload_type = kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; encoder_config->codec_type = kVideoCodecVP8; VideoReceiveStreamInterface::Decoder decoder = test::CreateMatchingDecoder(*send_config); @@ -125,10 +134,14 @@ TEST_F(FecEndToEndTest, ReceivesUlpfec) { (*receive_configs)[0].decoders.push_back(decoder); // Enable ULPFEC over RED. - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; - (*receive_configs)[0].rtp.red_payload_type = kRedPayloadType; - (*receive_configs)[0].rtp.ulpfec_payload_type = kUlpfecPayloadType; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + send_config->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; + (*receive_configs)[0].rtp.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + (*receive_configs)[0].rtp.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; (*receive_configs)[0].renderer = this; } @@ -159,7 +172,7 @@ class FlexfecRenderObserver : public test::EndToEndTest, static constexpr uint32_t kFlexfecLocalSsrc = 456; explicit FlexfecRenderObserver(bool enable_nack, bool expect_flexfec_rtcp) - : test::EndToEndTest(test::CallTest::kLongTimeout), + : test::EndToEndTest(test::VideoTestConstants::kLongTimeout), enable_nack_(enable_nack), expect_flexfec_rtcp_(expect_flexfec_rtcp), received_flexfec_rtcp_(false), @@ -175,27 +188,32 @@ class FlexfecRenderObserver : public test::EndToEndTest, EXPECT_TRUE(rtp_packet.Parse(packet, length)); EXPECT_TRUE( - rtp_packet.PayloadType() == test::CallTest::kFakeVideoSendPayloadType || - rtp_packet.PayloadType() == test::CallTest::kFlexfecPayloadType || - (enable_nack_ && - rtp_packet.PayloadType() == test::CallTest::kSendRtxPayloadType)) + rtp_packet.PayloadType() == + test::VideoTestConstants::kFakeVideoSendPayloadType || + rtp_packet.PayloadType() == + test::VideoTestConstants::kFlexfecPayloadType || + (enable_nack_ && rtp_packet.PayloadType() == + test::VideoTestConstants::kSendRtxPayloadType)) << "Unknown payload type received."; EXPECT_TRUE( - rtp_packet.Ssrc() == test::CallTest::kVideoSendSsrcs[0] || - rtp_packet.Ssrc() == test::CallTest::kFlexfecSendSsrc || - (enable_nack_ && rtp_packet.Ssrc() == test::CallTest::kSendRtxSsrcs[0])) + rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[0] || + rtp_packet.Ssrc() == test::VideoTestConstants::kFlexfecSendSsrc || + (enable_nack_ && + rtp_packet.Ssrc() == test::VideoTestConstants::kSendRtxSsrcs[0])) << "Unknown SSRC received."; // To reduce test flakiness, always let FlexFEC packets through. - if (rtp_packet.PayloadType() == test::CallTest::kFlexfecPayloadType) { - EXPECT_EQ(test::CallTest::kFlexfecSendSsrc, rtp_packet.Ssrc()); + if (rtp_packet.PayloadType() == + test::VideoTestConstants::kFlexfecPayloadType) { + EXPECT_EQ(test::VideoTestConstants::kFlexfecSendSsrc, rtp_packet.Ssrc()); return SEND_PACKET; } // To reduce test flakiness, always let RTX packets through. - if (rtp_packet.PayloadType() == test::CallTest::kSendRtxPayloadType) { - EXPECT_EQ(test::CallTest::kSendRtxSsrcs[0], rtp_packet.Ssrc()); + if (rtp_packet.PayloadType() == + test::VideoTestConstants::kSendRtxPayloadType) { + EXPECT_EQ(test::VideoTestConstants::kSendRtxSsrcs[0], rtp_packet.Ssrc()); if (rtp_packet.payload_size() == 0) { // Pure padding packet. @@ -223,9 +241,10 @@ class FlexfecRenderObserver : public test::EndToEndTest, // Simulate 5% video packet loss after rampup period. Record the // corresponding timestamps that were dropped. if (num_packets_sent_++ > 100 && random_.Rand(1, 100) <= 5) { - EXPECT_EQ(test::CallTest::kFakeVideoSendPayloadType, + EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType, rtp_packet.PayloadType()); - EXPECT_EQ(test::CallTest::kVideoSendSsrcs[0], rtp_packet.Ssrc()); + EXPECT_EQ(test::VideoTestConstants::kVideoSendSsrcs[0], + rtp_packet.Ssrc()); dropped_sequence_numbers_.insert(rtp_packet.SequenceNumber()); dropped_timestamps_.insert(rtp_packet.Timestamp()); @@ -246,7 +265,7 @@ class FlexfecRenderObserver : public test::EndToEndTest, parser.receiver_report()->report_blocks(); if (!report_blocks.empty()) { EXPECT_EQ(1U, report_blocks.size()); - EXPECT_EQ(test::CallTest::kFlexfecSendSsrc, + EXPECT_EQ(test::VideoTestConstants::kFlexfecSendSsrc, report_blocks[0].source_ssrc()); MutexLock lock(&mutex_); received_flexfec_rtcp_ = true; @@ -286,17 +305,20 @@ class FlexfecRenderObserver : public test::EndToEndTest, (*receive_configs)[0].renderer = this; if (enable_nack_) { - send_config->rtp.nack.rtp_history_ms = test::CallTest::kNackRtpHistoryMs; - send_config->rtp.rtx.ssrcs.push_back(test::CallTest::kSendRtxSsrcs[0]); - send_config->rtp.rtx.payload_type = test::CallTest::kSendRtxPayloadType; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[0]); + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; (*receive_configs)[0].rtp.nack.rtp_history_ms = - test::CallTest::kNackRtpHistoryMs; - (*receive_configs)[0].rtp.rtx_ssrc = test::CallTest::kSendRtxSsrcs[0]; - (*receive_configs)[0] - .rtp - .rtx_associated_payload_types[test::CallTest::kSendRtxPayloadType] = - test::CallTest::kVideoSendPayloadType; + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.rtx_ssrc = + test::VideoTestConstants::kSendRtxSsrcs[0]; + (*receive_configs)[0].rtp.rtx_associated_payload_types + [test::VideoTestConstants::kSendRtxPayloadType] = + test::VideoTestConstants::kVideoSendPayloadType; } } @@ -345,7 +367,7 @@ TEST_F(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) { class UlpfecNackObserver : public test::EndToEndTest { public: UlpfecNackObserver() - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), state_(kFirstPacket), ulpfec_sequence_number_(0), has_last_sequence_number_(false), @@ -359,12 +381,16 @@ TEST_F(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) { EXPECT_TRUE(rtp_packet.Parse(packet, length)); int encapsulated_payload_type = -1; - if (rtp_packet.PayloadType() == kRedPayloadType) { + if (rtp_packet.PayloadType() == + test::VideoTestConstants::kRedPayloadType) { encapsulated_payload_type = rtp_packet.payload()[0]; - if (encapsulated_payload_type != kFakeVideoSendPayloadType) - EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); + if (encapsulated_payload_type != + test::VideoTestConstants::kFakeVideoSendPayloadType) + EXPECT_EQ(test::VideoTestConstants::kUlpfecPayloadType, + encapsulated_payload_type); } else { - EXPECT_EQ(kFakeVideoSendPayloadType, rtp_packet.PayloadType()); + EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType, + rtp_packet.PayloadType()); } if (has_last_sequence_number_ && @@ -376,7 +402,8 @@ TEST_F(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) { last_sequence_number_ = rtp_packet.SequenceNumber(); has_last_sequence_number_ = true; - bool ulpfec_packet = encapsulated_payload_type == kUlpfecPayloadType; + bool ulpfec_packet = encapsulated_payload_type == + test::VideoTestConstants::kUlpfecPayloadType; switch (state_) { case kFirstPacket: state_ = kDropEveryOtherPacketUntilUlpfec; @@ -454,18 +481,25 @@ TEST_F(FecEndToEndTest, ReceivedUlpfecPacketsNotNacked) { std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { // Configure hybrid NACK/FEC. - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + send_config->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; // Set codec to VP8, otherwise NACK/FEC hybrid will be disabled. send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = "VP8"; - send_config->rtp.payload_type = kFakeVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kFakeVideoSendPayloadType; encoder_config->codec_type = kVideoCodecVP8; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - (*receive_configs)[0].rtp.red_payload_type = kRedPayloadType; - (*receive_configs)[0].rtp.ulpfec_payload_type = kUlpfecPayloadType; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + (*receive_configs)[0].rtp.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; (*receive_configs)[0].decoders.resize(1); (*receive_configs)[0].decoders[0].payload_type = diff --git a/third_party/libwebrtc/video/end_to_end_tests/frame_encryption_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/frame_encryption_tests.cc index 6a1b16927c95d..01f3db64aa95d 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/frame_encryption_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/frame_encryption_tests.cc @@ -15,6 +15,7 @@ #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "test/call_test.h" #include "test/gtest.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -29,7 +30,7 @@ class DecryptedFrameObserver : public test::EndToEndTest, public rtc::VideoSinkInterface { public: DecryptedFrameObserver() - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), encoder_factory_([] { return VP8Encoder::Create(); }) {} private: @@ -40,7 +41,8 @@ class DecryptedFrameObserver : public test::EndToEndTest, // Use VP8 instead of FAKE. send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = "VP8"; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; send_config->frame_encryptor = new FakeFrameEncryptor(); send_config->crypto_options.sframe.require_frame_encryption = true; encoder_config->codec_type = kVideoCodecVP8; diff --git a/third_party/libwebrtc/video/end_to_end_tests/histogram_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/histogram_tests.cc index 03e32ffba8731..fd35b0fbd4e85 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/histogram_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/histogram_tests.cc @@ -15,6 +15,7 @@ #include "system_wrappers/include/metrics.h" #include "test/call_test.h" #include "test/gtest.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -44,7 +45,7 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx, public rtc::VideoSinkInterface { public: FrameObserver(bool use_rtx, bool use_fec, bool screenshare) - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), use_rtx_(use_rtx), use_fec_(use_fec), screenshare_(screenshare), @@ -92,33 +93,43 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { // NACK - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; (*receive_configs)[0].renderer = this; // FEC if (use_fec_) { - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; + send_config->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = "VP8"; encoder_config->codec_type = kVideoCodecVP8; (*receive_configs)[0].decoders[0].video_format = SdpVideoFormat("VP8"); - (*receive_configs)[0].rtp.red_payload_type = kRedPayloadType; - (*receive_configs)[0].rtp.ulpfec_payload_type = kUlpfecPayloadType; + (*receive_configs)[0].rtp.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + (*receive_configs)[0].rtp.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; } // RTX if (use_rtx_) { - send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); - send_config->rtp.rtx.payload_type = kSendRtxPayloadType; - (*receive_configs)[0].rtp.rtx_ssrc = kSendRtxSsrcs[0]; - (*receive_configs)[0] - .rtp.rtx_associated_payload_types[kSendRtxPayloadType] = - kFakeVideoSendPayloadType; + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[0]); + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; + (*receive_configs)[0].rtp.rtx_ssrc = + test::VideoTestConstants::kSendRtxSsrcs[0]; + (*receive_configs)[0].rtp.rtx_associated_payload_types + [test::VideoTestConstants::kSendRtxPayloadType] = + test::VideoTestConstants::kFakeVideoSendPayloadType; if (use_fec_) { - send_config->rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType; - (*receive_configs)[0] - .rtp.rtx_associated_payload_types[kRtxRedPayloadType] = - kSendRtxPayloadType; + send_config->rtp.ulpfec.red_rtx_payload_type = + test::VideoTestConstants::kRtxRedPayloadType; + (*receive_configs)[0].rtp.rtx_associated_payload_types + [test::VideoTestConstants::kRtxRedPayloadType] = + test::VideoTestConstants::kSendRtxPayloadType; } } // RTT needed for RemoteNtpTimeEstimator for the receive stream. @@ -201,19 +212,24 @@ void HistogramTest::VerifyHistogramStats(bool use_rtx, EXPECT_METRIC_EQ( 1, metrics::NumSamples(video_prefix + "ReceivedHeightInPixels")); - EXPECT_METRIC_EQ(1, metrics::NumEvents(video_prefix + "InputWidthInPixels", - kDefaultWidth)); - EXPECT_METRIC_EQ(1, metrics::NumEvents(video_prefix + "InputHeightInPixels", - kDefaultHeight)); + EXPECT_METRIC_EQ(1, + metrics::NumEvents(video_prefix + "InputWidthInPixels", + test::VideoTestConstants::kDefaultWidth)); + EXPECT_METRIC_EQ( + 1, metrics::NumEvents(video_prefix + "InputHeightInPixels", + test::VideoTestConstants::kDefaultHeight)); + EXPECT_METRIC_EQ(1, + metrics::NumEvents(video_prefix + "SentWidthInPixels", + test::VideoTestConstants::kDefaultWidth)); EXPECT_METRIC_EQ( - 1, metrics::NumEvents(video_prefix + "SentWidthInPixels", kDefaultWidth)); - EXPECT_METRIC_EQ(1, metrics::NumEvents(video_prefix + "SentHeightInPixels", - kDefaultHeight)); - EXPECT_METRIC_EQ(1, metrics::NumEvents(video_prefix + "ReceivedWidthInPixels", - kDefaultWidth)); + 1, metrics::NumEvents(video_prefix + "SentHeightInPixels", + test::VideoTestConstants::kDefaultHeight)); EXPECT_METRIC_EQ(1, - metrics::NumEvents(video_prefix + "ReceivedHeightInPixels", - kDefaultHeight)); + metrics::NumEvents(video_prefix + "ReceivedWidthInPixels", + test::VideoTestConstants::kDefaultWidth)); + EXPECT_METRIC_EQ( + 1, metrics::NumEvents(video_prefix + "ReceivedHeightInPixels", + test::VideoTestConstants::kDefaultHeight)); EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "InputFramesPerSecond")); diff --git a/third_party/libwebrtc/video/end_to_end_tests/multi_codec_receive_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/multi_codec_receive_tests.cc index d8ac606bfdba2..e850a1114f3df 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/multi_codec_receive_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/multi_codec_receive_tests.cc @@ -24,6 +24,7 @@ #include "test/call_test.h" #include "test/gmock.h" #include "test/gtest.h" +#include "test/video_test_constants.h" using ::testing::Contains; @@ -36,11 +37,11 @@ constexpr int kFramesToObserve = 10; uint8_t PayloadNameToPayloadType(const std::string& payload_name) { if (payload_name == "VP8") { - return test::CallTest::kPayloadTypeVP8; + return test::VideoTestConstants::kPayloadTypeVP8; } else if (payload_name == "VP9") { - return test::CallTest::kPayloadTypeVP9; + return test::VideoTestConstants::kPayloadTypeVP9; } else if (payload_name == "H264") { - return test::CallTest::kPayloadTypeH264; + return test::VideoTestConstants::kPayloadTypeH264; } else { RTC_DCHECK_NOTREACHED(); return 0; @@ -63,7 +64,8 @@ int RemoveOlderOrEqual(uint32_t timestamp, std::vector* timestamps) { class FrameObserver : public test::RtpRtcpObserver, public rtc::VideoSinkInterface { public: - FrameObserver() : test::RtpRtcpObserver(test::CallTest::kDefaultTimeout) {} + FrameObserver() + : test::RtpRtcpObserver(test::VideoTestConstants::kDefaultTimeout) {} void Reset(uint8_t expected_payload_type) { MutexLock lock(&mutex_); @@ -79,7 +81,7 @@ class FrameObserver : public test::RtpRtcpObserver, RtpPacket rtp_packet; EXPECT_TRUE(rtp_packet.Parse(packet, length)); - EXPECT_EQ(rtp_packet.Ssrc(), test::CallTest::kVideoSendSsrcs[0]); + EXPECT_EQ(rtp_packet.Ssrc(), test::VideoTestConstants::kVideoSendSsrcs[0]); if (rtp_packet.payload_size() == 0) return SEND_PACKET; // Skip padding, may be sent after OnFrame is called. diff --git a/third_party/libwebrtc/video/end_to_end_tests/multi_stream_tester.cc b/third_party/libwebrtc/video/end_to_end_tests/multi_stream_tester.cc index 82e9eb941774d..8d993291945db 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/multi_stream_tester.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/multi_stream_tester.cc @@ -29,6 +29,7 @@ #include "rtc_base/task_queue_for_test.h" #include "test/call_test.h" #include "test/encoder_settings.h" +#include "test/video_test_constants.h" namespace webrtc { @@ -101,7 +102,8 @@ void MultiStreamTester::RunTest() { VideoReceiveStreamInterface::Config receive_config( receiver_transport.get()); receive_config.rtp.remote_ssrc = ssrc; - receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalVideoSsrc; + receive_config.rtp.local_ssrc = + test::VideoTestConstants::kReceiverLocalVideoSsrc; receive_config.decoder_factory = &decoder_factory; VideoReceiveStreamInterface::Decoder decoder = test::CreateMatchingDecoder(send_config); diff --git a/third_party/libwebrtc/video/end_to_end_tests/network_state_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/network_state_tests.cc index a39f9fe9e3cf4..a523465a082de 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/network_state_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/network_state_tests.cc @@ -104,8 +104,10 @@ void NetworkStateEndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState( GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory; CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer( + test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); Start(); }); @@ -131,8 +133,9 @@ void NetworkStateEndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState( CreateSendConfig(1, 0, 0); CreateMatchingReceiveConfigs(transport); CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); Start(); }); @@ -158,7 +161,7 @@ TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) { class NetworkStateTest : public test::EndToEndTest, public test::FakeEncoder { public: explicit NetworkStateTest(TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), e2e_test_task_queue_(task_queue), task_queue_(CreateDefaultTaskQueueFactory()->CreateTaskQueue( @@ -225,7 +228,8 @@ TEST_F(NetworkStateEndToEndTest, RespectsNetworkState) { } void PerformTest() override { - EXPECT_TRUE(encoded_frames_.Wait(kDefaultTimeout)) + EXPECT_TRUE( + encoded_frames_.Wait(test::VideoTestConstants::kDefaultTimeout)) << "No frames received by the encoder."; SendTask(task_queue_.get(), [this]() { diff --git a/third_party/libwebrtc/video/end_to_end_tests/resolution_bitrate_limits_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/resolution_bitrate_limits_tests.cc index 86167ac75ee36..e110fb759cebe 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/resolution_bitrate_limits_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/resolution_bitrate_limits_tests.cc @@ -18,6 +18,7 @@ #include "test/field_trial.h" #include "test/gtest.h" #include "test/video_encoder_proxy_factory.h" +#include "test/video_test_constants.h" #include "video/config/encoder_stream_factory.h" namespace webrtc { @@ -119,7 +120,7 @@ class InitEncodeTest : public test::EndToEndTest, InitEncodeTest(const std::string& payload_name, const std::vector& configs, const std::vector& expectations) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), encoder_factory_(this), payload_name_(payload_name), @@ -147,7 +148,8 @@ class InitEncodeTest : public test::EndToEndTest, webrtc::VideoEncoder::EncoderInfo encoder_info; send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = payload_name_; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; const VideoCodecType codec_type = PayloadStringToCodecType(payload_name_); encoder_config->codec_type = codec_type; encoder_config->video_stream_factory = diff --git a/third_party/libwebrtc/video/end_to_end_tests/retransmission_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/retransmission_tests.cc index 45a9dae1e8f2a..08b1bc85e47ec 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/retransmission_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/retransmission_tests.cc @@ -26,6 +26,7 @@ #include "test/field_trial.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -53,7 +54,7 @@ TEST_F(RetransmissionEndToEndTest, ReceivesAndRetransmitsNack) { class NackObserver : public test::EndToEndTest { public: NackObserver() - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), sent_rtp_packets_(0), packets_left_to_drop_(0), nacks_left_(kNumberOfNacksToObserve) {} @@ -108,8 +109,10 @@ TEST_F(RetransmissionEndToEndTest, ReceivesAndRetransmitsNack) { VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; } void PerformTest() override { @@ -133,7 +136,7 @@ TEST_F(RetransmissionEndToEndTest, ReceivesNackAndRetransmitsAudio) { class NackObserver : public test::EndToEndTest { public: NackObserver() - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), local_ssrc_(0), remote_ssrc_(0), receive_transport_(nullptr) {} @@ -172,7 +175,8 @@ TEST_F(RetransmissionEndToEndTest, ReceivesNackAndRetransmitsAudio) { void ModifyAudioConfigs(AudioSendStream::Config* send_config, std::vector* receive_configs) override { - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; local_ssrc_ = (*receive_configs)[0].rtp.local_ssrc; remote_ssrc_ = (*receive_configs)[0].rtp.remote_ssrc; receive_transport_ = (*receive_configs)[0].rtcp_send_transport; @@ -272,7 +276,7 @@ void RetransmissionEndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { public rtc::VideoSinkInterface { public: explicit PliObserver(int rtp_history_ms) - : EndToEndTest(kLongTimeout), + : EndToEndTest(test::VideoTestConstants::kLongTimeout), rtp_history_ms_(rtp_history_ms), nack_enabled_(rtp_history_ms > 0), highest_dropped_timestamp_(0), @@ -362,10 +366,11 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, public rtc::VideoSinkInterface { public: RetransmissionObserver(bool enable_rtx, bool enable_red) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), payload_type_(GetPayloadType(false, enable_red)), - retransmission_ssrc_(enable_rtx ? kSendRtxSsrcs[0] - : kVideoSendSsrcs[0]), + retransmission_ssrc_( + enable_rtx ? test::VideoTestConstants::kSendRtxSsrcs[0] + : test::VideoTestConstants::kVideoSendSsrcs[0]), retransmission_payload_type_(GetPayloadType(enable_rtx, enable_red)), encoder_factory_([]() { return VP8Encoder::Create(); }), marker_bits_observed_(0), @@ -417,7 +422,8 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; // Insert ourselves into the rendering pipeline. RTC_DCHECK(!orig_renderer_); @@ -427,27 +433,34 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, (*receive_configs)[0].enable_prerenderer_smoothing = false; (*receive_configs)[0].renderer = this; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - - if (payload_type_ == kRedPayloadType) { - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; - if (retransmission_ssrc_ == kSendRtxSsrcs[0]) - send_config->rtp.ulpfec.red_rtx_payload_type = kRtxRedPayloadType; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + + if (payload_type_ == test::VideoTestConstants::kRedPayloadType) { + send_config->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + if (retransmission_ssrc_ == test::VideoTestConstants::kSendRtxSsrcs[0]) + send_config->rtp.ulpfec.red_rtx_payload_type = + test::VideoTestConstants::kRtxRedPayloadType; (*receive_configs)[0].rtp.ulpfec_payload_type = send_config->rtp.ulpfec.ulpfec_payload_type; (*receive_configs)[0].rtp.red_payload_type = send_config->rtp.ulpfec.red_payload_type; } - if (retransmission_ssrc_ == kSendRtxSsrcs[0]) { - send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); - send_config->rtp.rtx.payload_type = kSendRtxPayloadType; - (*receive_configs)[0].rtp.rtx_ssrc = kSendRtxSsrcs[0]; - (*receive_configs)[0] - .rtp.rtx_associated_payload_types[(payload_type_ == kRedPayloadType) - ? kRtxRedPayloadType - : kSendRtxPayloadType] = + if (retransmission_ssrc_ == test::VideoTestConstants::kSendRtxSsrcs[0]) { + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[0]); + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; + (*receive_configs)[0].rtp.rtx_ssrc = + test::VideoTestConstants::kSendRtxSsrcs[0]; + (*receive_configs)[0].rtp.rtx_associated_payload_types + [(payload_type_ == test::VideoTestConstants::kRedPayloadType) + ? test::VideoTestConstants::kRtxRedPayloadType + : test::VideoTestConstants::kSendRtxPayloadType] = payload_type_; } // Configure encoding and decoding with VP8, since generic packetization @@ -472,12 +485,12 @@ void RetransmissionEndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, int GetPayloadType(bool use_rtx, bool use_fec) { if (use_fec) { if (use_rtx) - return kRtxRedPayloadType; - return kRedPayloadType; + return test::VideoTestConstants::kRtxRedPayloadType; + return test::VideoTestConstants::kRedPayloadType; } if (use_rtx) - return kSendRtxPayloadType; - return kFakeVideoSendPayloadType; + return test::VideoTestConstants::kSendRtxPayloadType; + return test::VideoTestConstants::kFakeVideoSendPayloadType; } Mutex mutex_; diff --git a/third_party/libwebrtc/video/end_to_end_tests/rtp_rtcp_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/rtp_rtcp_tests.cc index 10d274883db7e..009a3878fbbf7 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/rtp_rtcp_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/rtp_rtcp_tests.cc @@ -22,6 +22,7 @@ #include "test/call_test.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -41,7 +42,7 @@ void RtpRtcpEndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) { class RtcpModeObserver : public test::EndToEndTest { public: explicit RtcpModeObserver(RtcpMode rtcp_mode) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), rtcp_mode_(rtcp_mode), sent_rtp_(0), sent_rtcp_(0) {} @@ -94,8 +95,10 @@ void RtpRtcpEndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) { VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_; } @@ -168,12 +171,13 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation( class RtpSequenceObserver : public test::RtpRtcpObserver { public: explicit RtpSequenceObserver(bool use_rtx) - : test::RtpRtcpObserver(kDefaultTimeout), - ssrcs_to_observe_(kNumSimulcastStreams) { - for (size_t i = 0; i < kNumSimulcastStreams; ++i) { - ssrc_is_rtx_[kVideoSendSsrcs[i]] = false; + : test::RtpRtcpObserver(test::VideoTestConstants::kDefaultTimeout), + ssrcs_to_observe_(test::VideoTestConstants::kNumSimulcastStreams) { + for (size_t i = 0; i < test::VideoTestConstants::kNumSimulcastStreams; + ++i) { + ssrc_is_rtx_[test::VideoTestConstants::kVideoSendSsrcs[i]] = false; if (use_rtx) - ssrc_is_rtx_[kSendRtxSsrcs[i]] = true; + ssrc_is_rtx_[test::VideoTestConstants::kSendRtxSsrcs[i]] = true; } } @@ -188,7 +192,8 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation( uint32_t timestamp, bool only_padding) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_) { - static const int32_t kMaxTimestampGap = kDefaultTimeout.ms() * 90; + static const int32_t kMaxTimestampGap = + test::VideoTestConstants::kDefaultTimeout.ms() * 90; auto timestamp_it = last_observed_timestamp_.find(ssrc); if (timestamp_it == last_observed_timestamp_.end()) { EXPECT_FALSE(only_padding); @@ -285,13 +290,16 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation( CreateCalls(); CreateSendTransport(BuiltInNetworkBehaviorConfig(), &observer); CreateReceiveTransport(BuiltInNetworkBehaviorConfig(), &observer); - CreateSendConfig(kNumSimulcastStreams, 0, 0); + CreateSendConfig(test::VideoTestConstants::kNumSimulcastStreams, 0, 0); if (use_rtx) { - for (size_t i = 0; i < kNumSimulcastStreams; ++i) { - GetVideoSendConfig()->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); + for (size_t i = 0; i < test::VideoTestConstants::kNumSimulcastStreams; + ++i) { + GetVideoSendConfig()->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[i]); } - GetVideoSendConfig()->rtp.rtx.payload_type = kSendRtxPayloadType; + GetVideoSendConfig()->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; } GetVideoEncoderConfig()->video_stream_factory = @@ -341,7 +349,7 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation( GetVideoSendStream()->ReconfigureVideoEncoder( GetVideoEncoderConfig()->Copy()); }); - observer.ResetExpectedSsrcs(kNumSimulcastStreams); + observer.ResetExpectedSsrcs(test::VideoTestConstants::kNumSimulcastStreams); EXPECT_TRUE(observer.Wait()) << "Timed out waiting for all SSRCs to send packets."; @@ -357,7 +365,7 @@ void RtpRtcpEndToEndTest::TestRtpStatePreservation( GetVideoSendStream()->ReconfigureVideoEncoder( GetVideoEncoderConfig()->Copy()); }); - observer.ResetExpectedSsrcs(kNumSimulcastStreams); + observer.ResetExpectedSsrcs(test::VideoTestConstants::kNumSimulcastStreams); EXPECT_TRUE(observer.Wait()) << "Timed out waiting for all SSRCs to send packets."; } @@ -387,7 +395,7 @@ TEST_F(RtpRtcpEndToEndTest, DISABLED_TestFlexfecRtpStatePreservation) { class RtpSequenceObserver : public test::RtpRtcpObserver { public: RtpSequenceObserver() - : test::RtpRtcpObserver(kDefaultTimeout), + : test::RtpRtcpObserver(test::VideoTestConstants::kDefaultTimeout), num_flexfec_packets_sent_(0) {} void ResetPacketCount() { @@ -405,10 +413,12 @@ TEST_F(RtpRtcpEndToEndTest, DISABLED_TestFlexfecRtpStatePreservation) { const uint32_t timestamp = rtp_packet.Timestamp(); const uint32_t ssrc = rtp_packet.Ssrc(); - if (ssrc == kVideoSendSsrcs[0] || ssrc == kSendRtxSsrcs[0]) { + if (ssrc == test::VideoTestConstants::kVideoSendSsrcs[0] || + ssrc == test::VideoTestConstants::kSendRtxSsrcs[0]) { return SEND_PACKET; } - EXPECT_EQ(kFlexfecSendSsrc, ssrc) << "Unknown SSRC sent."; + EXPECT_EQ(test::VideoTestConstants::kFlexfecSendSsrc, ssrc) + << "Unknown SSRC sent."; ++num_flexfec_packets_sent_; @@ -476,18 +486,24 @@ TEST_F(RtpRtcpEndToEndTest, DISABLED_TestFlexfecRtpStatePreservation) { GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory; GetVideoSendConfig()->rtp.payload_name = "VP8"; - GetVideoSendConfig()->rtp.payload_type = kVideoSendPayloadType; - GetVideoSendConfig()->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - GetVideoSendConfig()->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); - GetVideoSendConfig()->rtp.rtx.payload_type = kSendRtxPayloadType; + GetVideoSendConfig()->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; + GetVideoSendConfig()->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + GetVideoSendConfig()->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[0]); + GetVideoSendConfig()->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; GetVideoEncoderConfig()->codec_type = kVideoCodecVP8; CreateMatchingReceiveConfigs(); - video_receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - video_receive_configs_[0].rtp.rtx_ssrc = kSendRtxSsrcs[0]; - video_receive_configs_[0] - .rtp.rtx_associated_payload_types[kSendRtxPayloadType] = - kVideoSendPayloadType; + video_receive_configs_[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + video_receive_configs_[0].rtp.rtx_ssrc = + test::VideoTestConstants::kSendRtxSsrcs[0]; + video_receive_configs_[0].rtp.rtx_associated_payload_types + [test::VideoTestConstants::kSendRtxPayloadType] = + test::VideoTestConstants::kVideoSendPayloadType; // The matching FlexFEC receive config is not created by // CreateMatchingReceiveConfigs since this is not a test::BaseTest. @@ -500,7 +516,8 @@ TEST_F(RtpRtcpEndToEndTest, DISABLED_TestFlexfecRtpStatePreservation) { GetVideoSendConfig()->rtp.flexfec.ssrc; flexfec_receive_config.protected_media_ssrcs = GetVideoSendConfig()->rtp.flexfec.protected_media_ssrcs; - flexfec_receive_config.rtp.local_ssrc = kReceiverLocalVideoSsrc; + flexfec_receive_config.rtp.local_ssrc = + test::VideoTestConstants::kReceiverLocalVideoSsrc; flexfec_receive_configs_.push_back(flexfec_receive_config); CreateFlexfecStreams(); diff --git a/third_party/libwebrtc/video/end_to_end_tests/ssrc_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/ssrc_tests.cc index edacde115a2e5..296e7c35099ac 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/ssrc_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/ssrc_tests.cc @@ -21,6 +21,7 @@ #include "test/call_test.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" namespace webrtc { class SsrcEndToEndTest : public test::CallTest { @@ -37,12 +38,14 @@ class SsrcEndToEndTest : public test::CallTest { TEST_F(SsrcEndToEndTest, ReceiverUsesLocalSsrc) { class SyncRtcpObserver : public test::EndToEndTest { public: - SyncRtcpObserver() : EndToEndTest(kDefaultTimeout) {} + SyncRtcpObserver() + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout) {} Action OnReceiveRtcp(const uint8_t* packet, size_t length) override { test::RtcpPacketParser parser; EXPECT_TRUE(parser.Parse(packet, length)); - EXPECT_EQ(kReceiverLocalVideoSsrc, parser.sender_ssrc()); + EXPECT_EQ(test::VideoTestConstants::kReceiverLocalVideoSsrc, + parser.sender_ssrc()); observation_complete_.Set(); return SEND_PACKET; @@ -64,7 +67,8 @@ TEST_F(SsrcEndToEndTest, UnknownRtpPacketTriggersUndemuxablePacketHandler) { : receiver_(receiver) {} bool Wait() { - return undemuxable_packet_handler_triggered_.Wait(kDefaultTimeout); + return undemuxable_packet_handler_triggered_.Wait( + test::VideoTestConstants::kDefaultTimeout); } private: @@ -119,8 +123,10 @@ TEST_F(SsrcEndToEndTest, UnknownRtpPacketTriggersUndemuxablePacketHandler) { CreateMatchingReceiveConfigs(receive_transport.get()); CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer( + test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); Start(); receiver_call_->DestroyVideoReceiveStream(video_receive_streams_[0]); @@ -147,7 +153,7 @@ void SsrcEndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, size_t num_ssrcs, bool send_single_ssrc_first, TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), num_ssrcs_(num_ssrcs), send_single_ssrc_first_(send_single_ssrc_first), ssrcs_to_observe_(num_ssrcs), @@ -236,7 +242,8 @@ void SsrcEndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, VideoSendStream* send_stream_; VideoEncoderConfig video_encoder_config_all_streams_; TaskQueueBase* task_queue_; - } test(kVideoSendSsrcs, num_ssrcs, send_single_ssrc_first, task_queue()); + } test(test::VideoTestConstants::kVideoSendSsrcs, num_ssrcs, + send_single_ssrc_first, task_queue()); RunBaseTest(&test); } @@ -246,21 +253,22 @@ TEST_F(SsrcEndToEndTest, SendsSetSsrc) { } TEST_F(SsrcEndToEndTest, SendsSetSimulcastSsrcs) { - TestSendsSetSsrcs(kNumSimulcastStreams, false); + TestSendsSetSsrcs(test::VideoTestConstants::kNumSimulcastStreams, false); } TEST_F(SsrcEndToEndTest, CanSwitchToUseAllSsrcs) { - TestSendsSetSsrcs(kNumSimulcastStreams, true); + TestSendsSetSsrcs(test::VideoTestConstants::kNumSimulcastStreams, true); } TEST_F(SsrcEndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { class ObserveRedundantPayloads : public test::EndToEndTest { public: ObserveRedundantPayloads() - : EndToEndTest(kDefaultTimeout), - ssrcs_to_observe_(kNumSimulcastStreams) { - for (size_t i = 0; i < kNumSimulcastStreams; ++i) { - registered_rtx_ssrc_[kSendRtxSsrcs[i]] = true; + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), + ssrcs_to_observe_(test::VideoTestConstants::kNumSimulcastStreams) { + for (size_t i = 0; i < test::VideoTestConstants::kNumSimulcastStreams; + ++i) { + registered_rtx_ssrc_[test::VideoTestConstants::kSendRtxSsrcs[i]] = true; } } @@ -286,7 +294,9 @@ TEST_F(SsrcEndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { return SEND_PACKET; } - size_t GetNumVideoStreams() const override { return kNumSimulcastStreams; } + size_t GetNumVideoStreams() const override { + return test::VideoTestConstants::kNumSimulcastStreams; + } void ModifyVideoConfigs( VideoSendStream::Config* send_config, @@ -299,10 +309,13 @@ TEST_F(SsrcEndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { layer.target_bitrate_bps = 15000; layer.max_bitrate_bps = 20000; } - send_config->rtp.rtx.payload_type = kSendRtxPayloadType; + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; - for (size_t i = 0; i < kNumSimulcastStreams; ++i) - send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); + for (size_t i = 0; i < test::VideoTestConstants::kNumSimulcastStreams; + ++i) + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[i]); // Significantly higher than max bitrates for all video streams -> forcing // padding to trigger redundant padding on all RTX SSRCs. diff --git a/third_party/libwebrtc/video/end_to_end_tests/stats_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/stats_tests.cc index 147227d941081..4a1c093da746d 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/stats_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/stats_tests.cc @@ -28,6 +28,7 @@ #include "test/fake_encoder.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -51,7 +52,8 @@ TEST_F(StatsEndToEndTest, GetStats) { class StatsObserver : public test::EndToEndTest { public: StatsObserver() - : EndToEndTest(kLongTimeout), encoder_factory_([]() { + : EndToEndTest(test::VideoTestConstants::kLongTimeout), + encoder_factory_([]() { return std::make_unique( Clock::GetRealTimeClock(), 10); }) {} @@ -135,9 +137,11 @@ TEST_F(StatsEndToEndTest, GetStats) { stats.rtcp_packet_type_counts.unique_nack_requests != 0; RTC_DCHECK(stats.current_payload_type == -1 || - stats.current_payload_type == kFakeVideoSendPayloadType); + stats.current_payload_type == + test::VideoTestConstants::kFakeVideoSendPayloadType); receive_stats_filled_["IncomingPayloadType"] |= - stats.current_payload_type == kFakeVideoSendPayloadType; + stats.current_payload_type == + test::VideoTestConstants::kFakeVideoSendPayloadType; } return AllStatsFilled(receive_stats_filled_); @@ -150,7 +154,8 @@ TEST_F(StatsEndToEndTest, GetStats) { SendTask(task_queue_, [&]() { stats = send_stream_->GetStats(); }); size_t expected_num_streams = - kNumSimulcastStreams + expected_send_ssrcs_.size(); + test::VideoTestConstants::kNumSimulcastStreams + + expected_send_ssrcs_.size(); send_stats_filled_["NumStreams"] |= stats.substreams.size() == expected_num_streams; @@ -252,8 +257,10 @@ TEST_F(StatsEndToEndTest, GetStats) { } send_config->rtp.c_name = "SomeCName"; - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - send_config->rtp.rtx.payload_type = kSendRtxPayloadType; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; const std::vector& ssrcs = send_config->rtp.ssrcs; for (size_t i = 0; i < ssrcs.size(); ++i) { @@ -261,23 +268,29 @@ TEST_F(StatsEndToEndTest, GetStats) { expected_receive_ssrcs_.push_back( (*receive_configs)[i].rtp.remote_ssrc); (*receive_configs)[i].render_delay_ms = kExpectedRenderDelayMs; - (*receive_configs)[i].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - - (*receive_configs)[i].rtp.rtx_ssrc = kSendRtxSsrcs[i]; - (*receive_configs)[i] - .rtp.rtx_associated_payload_types[kSendRtxPayloadType] = - kFakeVideoSendPayloadType; + (*receive_configs)[i].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + + (*receive_configs)[i].rtp.rtx_ssrc = + test::VideoTestConstants::kSendRtxSsrcs[i]; + (*receive_configs)[i].rtp.rtx_associated_payload_types + [test::VideoTestConstants::kSendRtxPayloadType] = + test::VideoTestConstants::kFakeVideoSendPayloadType; } - for (size_t i = 0; i < kNumSimulcastStreams; ++i) - send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); + for (size_t i = 0; i < test::VideoTestConstants::kNumSimulcastStreams; + ++i) + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[i]); // Use a delayed encoder to make sure we see CpuOveruseMetrics stats that // are non-zero. send_config->encoder_settings.encoder_factory = &encoder_factory_; } - size_t GetNumVideoStreams() const override { return kNumSimulcastStreams; } + size_t GetNumVideoStreams() const override { + return test::VideoTestConstants::kNumSimulcastStreams; + } void OnVideoStreamsCreated(VideoSendStream* send_stream, const std::vector& @@ -290,7 +303,8 @@ TEST_F(StatsEndToEndTest, GetStats) { void PerformTest() override { Clock* clock = Clock::GetRealTimeClock(); int64_t now_ms = clock->TimeInMilliseconds(); - int64_t stop_time_ms = now_ms + test::CallTest::kLongTimeout.ms(); + int64_t stop_time_ms = + now_ms + test::VideoTestConstants::kLongTimeout.ms(); bool receive_ok = false; bool send_ok = false; @@ -347,7 +361,7 @@ TEST_F(StatsEndToEndTest, TimingFramesAreReported) { class StatsObserver : public test::EndToEndTest { public: - StatsObserver() : EndToEndTest(kLongTimeout) {} + StatsObserver() : EndToEndTest(test::VideoTestConstants::kLongTimeout) {} private: void ModifyVideoConfigs( @@ -395,7 +409,8 @@ TEST_F(StatsEndToEndTest, TestReceivedRtpPacketStats) { class ReceivedRtpStatsObserver : public test::EndToEndTest { public: explicit ReceivedRtpStatsObserver(TaskQueueBase* task_queue) - : EndToEndTest(kDefaultTimeout), task_queue_(task_queue) {} + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), + task_queue_(task_queue) {} private: void OnVideoStreamsCreated(VideoSendStream* send_stream, @@ -447,7 +462,9 @@ TEST_F(StatsEndToEndTest, MAYBE_ContentTypeSwitches) { class StatsObserver : public test::BaseTest, public rtc::VideoSinkInterface { public: - StatsObserver() : BaseTest(kLongTimeout), num_frames_received_(0) {} + StatsObserver() + : BaseTest(test::VideoTestConstants::kLongTimeout), + num_frames_received_(0) {} bool ShouldCreateReceivers() const override { return true; } @@ -512,8 +529,10 @@ TEST_F(StatsEndToEndTest, MAYBE_ContentTypeSwitches) { CreateMatchingReceiveConfigs(); // Modify send and receive configs. - GetVideoSendConfig()->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - video_receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + GetVideoSendConfig()->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + video_receive_configs_[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; video_receive_configs_[0].renderer = &test; // RTT needed for RemoteNtpTimeEstimator for the receive stream. video_receive_configs_[0].rtp.rtcp_xr.receiver_reference_time_report = @@ -527,8 +546,10 @@ TEST_F(StatsEndToEndTest, MAYBE_ContentTypeSwitches) { VideoEncoderConfig::ContentType::kScreen; CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer( + test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); Start(); }); @@ -572,7 +593,8 @@ TEST_F(StatsEndToEndTest, VerifyNackStats) { class NackObserver : public test::EndToEndTest { public: explicit NackObserver(TaskQueueBase* task_queue) - : EndToEndTest(kLongTimeout), task_queue_(task_queue) {} + : EndToEndTest(test::VideoTestConstants::kLongTimeout), + task_queue_(task_queue) {} private: Action OnSendRtp(const uint8_t* packet, size_t length) override { @@ -638,8 +660,10 @@ TEST_F(StatsEndToEndTest, VerifyNackStats) { VideoSendStream::Config* send_config, std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + (*receive_configs)[0].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; } void OnVideoStreamsCreated(VideoSendStream* send_stream, @@ -695,8 +719,9 @@ TEST_F(StatsEndToEndTest, CallReportsRttForSender) { CreateMatchingReceiveConfigs(); CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp); Start(); }); @@ -706,7 +731,7 @@ TEST_F(StatsEndToEndTest, CallReportsRttForSender) { Call::Stats stats; SendTask(task_queue(), [this, &stats]() { stats = sender_call_->GetStats(); }); - ASSERT_GE(start_time_ms + kDefaultTimeout.ms(), + ASSERT_GE(start_time_ms + test::VideoTestConstants::kDefaultTimeout.ms(), clock_->TimeInMilliseconds()) << "No RTT stats before timeout!"; if (stats.rtt_ms != -1) { diff --git a/third_party/libwebrtc/video/end_to_end_tests/transport_feedback_tests.cc b/third_party/libwebrtc/video/end_to_end_tests/transport_feedback_tests.cc index 0703f29f515df..33cddcecaaa3d 100644 --- a/third_party/libwebrtc/video/end_to_end_tests/transport_feedback_tests.cc +++ b/third_party/libwebrtc/video/end_to_end_tests/transport_feedback_tests.cc @@ -26,6 +26,7 @@ #include "test/field_trial.h" #include "test/gtest.h" #include "test/rtcp_packet_parser.h" +#include "test/video_test_constants.h" #include "video/end_to_end_tests/multi_stream_tester.h" namespace webrtc { @@ -251,7 +252,7 @@ class TransportFeedbackEndToEndTest : public test::CallTest { class TransportFeedbackTester : public test::EndToEndTest { public: TransportFeedbackTester(size_t num_video_streams, size_t num_audio_streams) - : EndToEndTest(::webrtc::TransportFeedbackEndToEndTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), num_video_streams_(num_video_streams), num_audio_streams_(num_audio_streams), receiver_call_(nullptr) { @@ -279,7 +280,8 @@ class TransportFeedbackTester : public test::EndToEndTest { } void PerformTest() override { - EXPECT_TRUE(observation_complete_.Wait(test::CallTest::kDefaultTimeout)); + EXPECT_TRUE( + observation_complete_.Wait(test::VideoTestConstants::kDefaultTimeout)); } void OnCallsCreated(Call* sender_call, Call* receiver_call) override { @@ -326,8 +328,7 @@ TEST_F(TransportFeedbackEndToEndTest, class TransportFeedbackTester : public test::EndToEndTest { public: TransportFeedbackTester(size_t num_video_streams, size_t num_audio_streams) - : EndToEndTest( - ::webrtc::TransportFeedbackEndToEndTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), num_video_streams_(num_video_streams), num_audio_streams_(num_audio_streams), media_sent_(0), @@ -415,7 +416,7 @@ TEST_F(TransportFeedbackEndToEndTest, TransportSeqNumOnAudioAndVideo) { class TransportSequenceNumberTest : public test::EndToEndTest { public: TransportSequenceNumberTest() - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), video_observed_(false), audio_observed_(false) { extensions_.Register( @@ -444,9 +445,9 @@ TEST_F(TransportFeedbackEndToEndTest, TransportSeqNumOnAudioAndVideo) { int64_t packet_id = unwrapper_.Unwrap(transport_sequence_number); EXPECT_TRUE(received_packet_ids_.insert(packet_id).second); - if (rtp_packet.Ssrc() == kVideoSendSsrcs[0]) + if (rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[0]) video_observed_ = true; - if (rtp_packet.Ssrc() == kAudioSendSsrc) + if (rtp_packet.Ssrc() == test::VideoTestConstants::kAudioSendSsrc) audio_observed_ = true; if (audio_observed_ && video_observed_ && received_packet_ids_.size() >= kMinPacketsToWaitFor) { diff --git a/third_party/libwebrtc/video/full_stack_tests.cc b/third_party/libwebrtc/video/full_stack_tests.cc index cddf98343d265..7791afc854ff7 100644 --- a/third_party/libwebrtc/video/full_stack_tests.cc +++ b/third_party/libwebrtc/video/full_stack_tests.cc @@ -726,6 +726,54 @@ TEST(FullStackTest, Conference_Motion_Hd_3tl_Alt_Heavy_Moderate_Limits) { fixture->RunWithAnalyzer(conf_motion_hd); } +TEST(FullStackTest, Foreman_Cif_30kbps_AV1) { + auto fixture = CreateVideoQualityTestFixture(); + ParamsWithLogging foreman_cif; + foreman_cif.call.send_side_bwe = true; + foreman_cif.video[0] = {.enabled = true, + .width = 352, + .height = 288, + .fps = 10, + .min_bitrate_bps = 20'000, + .target_bitrate_bps = 30'000, + .max_bitrate_bps = 100'000, + .codec = "AV1", + .num_temporal_layers = 1, + .selected_tl = 0, + .clip_path = ClipNameToClipPath("foreman_cif")}; + foreman_cif.analyzer = {.test_label = "foreman_cif_30kbps_AV1", + .test_durations_secs = kFullStackTestDurationSecs}; + foreman_cif.config->link_capacity_kbps = 30; + foreman_cif.call.generic_descriptor = true; + fixture->RunWithAnalyzer(foreman_cif); +} + +TEST(FullStackTest, Conference_Motion_Hd_3tl_AV1) { + auto fixture = CreateVideoQualityTestFixture(); + ParamsWithLogging conf_motion_hd; + conf_motion_hd.call.send_side_bwe = true; + conf_motion_hd.video[0] = { + .enabled = true, + .width = 1280, + .height = 720, + .fps = 50, + .min_bitrate_bps = 20'000, + .target_bitrate_bps = 500'000, + .max_bitrate_bps = 1'000'000, + .codec = "AV1", + .num_temporal_layers = 3, + .clip_path = ClipNameToClipPath("ConferenceMotion_1280_720_50")}; + + conf_motion_hd.analyzer = {.test_label = "conference_motion_hd_3tl_AV1", + .test_durations_secs = kFullStackTestDurationSecs}; + conf_motion_hd.config->queue_length_packets = 50; + conf_motion_hd.config->loss_percent = 3; + conf_motion_hd.config->queue_delay_ms = 100; + conf_motion_hd.config->link_capacity_kbps = 1000; + conf_motion_hd.call.generic_descriptor = true; + fixture->RunWithAnalyzer(conf_motion_hd); +} + #if defined(RTC_ENABLE_VP9) TEST(FullStackTest, Conference_Motion_Hd_2000kbps_100ms_32pkts_Queue_Vp9) { auto fixture = CreateVideoQualityTestFixture(); diff --git a/third_party/libwebrtc/video/picture_id_tests.cc b/third_party/libwebrtc/video/picture_id_tests.cc index 06491b924af65..60d3f5211a998 100644 --- a/third_party/libwebrtc/video/picture_id_tests.cc +++ b/third_party/libwebrtc/video/picture_id_tests.cc @@ -25,6 +25,7 @@ #include "rtc_base/synchronization/mutex.h" #include "rtc_base/task_queue_for_test.h" #include "test/call_test.h" +#include "test/video_test_constants.h" namespace webrtc { namespace { @@ -43,7 +44,7 @@ const size_t kNumTemporalLayers[] = {1, 2, 3}; class PictureIdObserver : public test::RtpRtcpObserver { public: explicit PictureIdObserver(VideoCodecType codec_type) - : test::RtpRtcpObserver(test::CallTest::kDefaultTimeout), + : test::RtpRtcpObserver(test::VideoTestConstants::kDefaultTimeout), depacketizer_(CreateVideoRtpDepacketizer(codec_type)), max_expected_picture_id_gap_(0), max_expected_tl0_idx_gap_(0), @@ -84,9 +85,10 @@ class PictureIdObserver : public test::RtpRtcpObserver { ParsedPacket* parsed) const { RtpPacket rtp_packet; EXPECT_TRUE(rtp_packet.Parse(packet, length)); - EXPECT_TRUE(rtp_packet.Ssrc() == test::CallTest::kVideoSendSsrcs[0] || - rtp_packet.Ssrc() == test::CallTest::kVideoSendSsrcs[1] || - rtp_packet.Ssrc() == test::CallTest::kVideoSendSsrcs[2]) + EXPECT_TRUE( + rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[0] || + rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[1] || + rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[2]) << "Unknown SSRC sent."; if (rtp_packet.payload_size() == 0) { @@ -257,7 +259,8 @@ void PictureIdTest::SetupEncoder(VideoEncoderFactory* encoder_factory, task_queue(), [this, encoder_factory, payload_name]() { CreateCalls(); CreateSendTransport(BuiltInNetworkBehaviorConfig(), observer_.get()); - CreateSendConfig(kNumSimulcastStreams, 0, 0, send_transport_.get()); + CreateSendConfig(test::VideoTestConstants::kNumSimulcastStreams, 0, 0, + send_transport_.get()); GetVideoSendConfig()->encoder_settings.encoder_factory = encoder_factory; GetVideoSendConfig()->rtp.payload_name = payload_name; diff --git a/third_party/libwebrtc/video/quality_scaling_tests.cc b/third_party/libwebrtc/video/quality_scaling_tests.cc index 7eaf14831b38e..b6f15757fb630 100644 --- a/third_party/libwebrtc/video/quality_scaling_tests.cc +++ b/third_party/libwebrtc/video/quality_scaling_tests.cc @@ -19,6 +19,7 @@ #include "test/call_test.h" #include "test/field_trial.h" #include "test/frame_generator_capturer.h" +#include "test/video_test_constants.h" #include "video/config/encoder_stream_factory.h" namespace webrtc { @@ -126,7 +127,8 @@ class ScalingObserver : public test::SendTest { VideoEncoder::EncoderInfo encoder_info; send_config->encoder_settings.encoder_factory = &encoder_factory_; send_config->rtp.payload_name = payload_name_; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; encoder_config->video_format.name = payload_name_; const VideoCodecType codec_type = PayloadStringToCodecType(payload_name_); encoder_config->codec_type = codec_type; @@ -155,6 +157,15 @@ class ScalingObserver : public test::SendTest { test_params_.size()); } + Action OnSendRtp(const uint8_t* packet, size_t length) override { + // The tests are expected to send at the configured start bitrate. Do not + // send any packets to avoid receiving REMB and possibly go down in target + // bitrate. A low bitrate estimate could result in downgrading due to other + // reasons than low/high QP-value (e.g. high frame drop percent) or not + // upgrading due to bitrate constraint. + return DROP_PACKET; + } + void PerformTest() override { EXPECT_EQ(expect_scaling_, Wait()); } test::FunctionVideoEncoderFactory encoder_factory_; diff --git a/third_party/libwebrtc/video/send_statistics_proxy_unittest.cc b/third_party/libwebrtc/video/send_statistics_proxy_unittest.cc index 923057907ad62..d3d14d6859a8c 100644 --- a/third_party/libwebrtc/video/send_statistics_proxy_unittest.cc +++ b/third_party/libwebrtc/video/send_statistics_proxy_unittest.cc @@ -194,14 +194,14 @@ TEST_F(SendStatisticsProxyTest, ReportBlockDataObserver) { for (uint32_t ssrc : config_.rtp.ssrcs) { // Add statistics with some arbitrary, but unique, numbers. uint32_t offset = ssrc * 4; - RTCPReportBlock report_block; - report_block.source_ssrc = ssrc; - report_block.packets_lost = offset; - report_block.extended_highest_sequence_number = offset + 1; - report_block.fraction_lost = offset + 2; - report_block.jitter = offset + 3; + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(ssrc); + report_block.SetCumulativeLost(offset); + report_block.SetExtHighestSeqNum(offset + 1); + report_block.SetFractionLost(offset + 2); + report_block.SetJitter(offset + 3); ReportBlockData data; - data.SetReportBlock(report_block, 0); + data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero()); expected_.substreams[ssrc].report_block_data = data; callback->OnReportBlockDataUpdated(data); @@ -209,14 +209,14 @@ TEST_F(SendStatisticsProxyTest, ReportBlockDataObserver) { for (uint32_t ssrc : config_.rtp.rtx.ssrcs) { // Add statistics with some arbitrary, but unique, numbers. uint32_t offset = ssrc * 4; - RTCPReportBlock report_block; - report_block.source_ssrc = ssrc; - report_block.packets_lost = offset; - report_block.extended_highest_sequence_number = offset + 1; - report_block.fraction_lost = offset + 2; - report_block.jitter = offset + 3; + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(ssrc); + report_block.SetCumulativeLost(offset); + report_block.SetExtHighestSeqNum(offset + 1); + report_block.SetFractionLost(offset + 2); + report_block.SetJitter(offset + 3); ReportBlockData data; - data.SetReportBlock(report_block, 0); + data.SetReportBlock(/*sender_ssrc=*/0, report_block, Timestamp::Zero()); expected_.substreams[ssrc].report_block_data = data; callback->OnReportBlockDataUpdated(data); @@ -2311,10 +2311,10 @@ TEST_F(SendStatisticsProxyTest, NoSubstreams) { 1; // From ReportBlockDataObserver. ReportBlockDataObserver* rtcp_callback = statistics_proxy_.get(); - RTCPReportBlock report_block; - report_block.source_ssrc = excluded_ssrc; + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(excluded_ssrc); ReportBlockData data; - data.SetReportBlock(report_block, 0); + data.SetReportBlock(0, report_block, Timestamp::Zero()); rtcp_callback->OnReportBlockDataUpdated(data); // From BitrateStatisticsObserver. @@ -2363,10 +2363,10 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) { // Update the first SSRC with bogus RTCP stats to make sure that encoded // resolution still times out (no global timeout for all stats). ReportBlockDataObserver* rtcp_callback = statistics_proxy_.get(); - RTCPReportBlock report_block; - report_block.source_ssrc = config_.rtp.ssrcs[0]; + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(config_.rtp.ssrcs[0]); ReportBlockData data; - data.SetReportBlock(report_block, 0); + data.SetReportBlock(0, report_block, Timestamp::Zero()); rtcp_callback->OnReportBlockDataUpdated(data); // Report stats for second SSRC to make sure it's not outdated along with the diff --git a/third_party/libwebrtc/video/video_analyzer.cc b/third_party/libwebrtc/video/video_analyzer.cc index 6d70762f34c2d..24bcfc9c8fc47 100644 --- a/third_party/libwebrtc/video/video_analyzer.cc +++ b/third_party/libwebrtc/video/video_analyzer.cc @@ -34,6 +34,7 @@ #include "test/testsupport/file_utils.h" #include "test/testsupport/frame_writer.h" #include "test/testsupport/test_artifacts.h" +#include "test/video_test_constants.h" ABSL_FLAG(bool, save_worst_frame, @@ -59,7 +60,7 @@ constexpr int kKeepAliveIntervalIterations = kKeepAliveInterval.ms() / kProbingInterval.ms(); bool IsFlexfec(int payload_type) { - return payload_type == test::CallTest::kFlexfecPayloadType; + return payload_type == test::VideoTestConstants::kFlexfecPayloadType; } } // namespace @@ -437,7 +438,7 @@ double VideoAnalyzer::GetCpuUsagePercent() { bool VideoAnalyzer::IsInSelectedSpatialAndTemporalLayer( const RtpPacket& rtp_packet) { - if (rtp_packet.PayloadType() == test::CallTest::kPayloadTypeVP8) { + if (rtp_packet.PayloadType() == test::VideoTestConstants::kPayloadTypeVP8) { auto parsed_payload = vp8_depacketizer_->Parse(rtp_packet.PayloadBuffer()); RTC_DCHECK(parsed_payload); const auto& vp8_header = absl::get( @@ -447,7 +448,7 @@ bool VideoAnalyzer::IsInSelectedSpatialAndTemporalLayer( temporal_idx <= selected_tl_; } - if (rtp_packet.PayloadType() == test::CallTest::kPayloadTypeVP9) { + if (rtp_packet.PayloadType() == test::VideoTestConstants::kPayloadTypeVP9) { auto parsed_payload = vp9_depacketizer_->Parse(rtp_packet.PayloadBuffer()); RTC_DCHECK(parsed_payload); const auto& vp9_header = absl::get( diff --git a/third_party/libwebrtc/video/video_quality_test.cc b/third_party/libwebrtc/video/video_quality_test.cc index 1e717741e129b..2dd80eada6d93 100644 --- a/third_party/libwebrtc/video/video_quality_test.cc +++ b/third_party/libwebrtc/video/video_quality_test.cc @@ -54,6 +54,7 @@ #ifdef WEBRTC_WIN #include "modules/audio_device/include/audio_device_factory.h" #endif +#include "test/video_test_constants.h" #include "video/config/encoder_stream_factory.h" namespace webrtc { @@ -714,26 +715,26 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, RTC_CHECK_GT(num_video_substreams, 0); for (size_t i = 0; i < num_video_substreams; ++i) video_send_configs_[video_idx].rtp.ssrcs.push_back( - kVideoSendSsrcs[total_streams_used + i]); + test::VideoTestConstants::kVideoSendSsrcs[total_streams_used + i]); int payload_type; if (params_.video[video_idx].codec == "H264") { - payload_type = kPayloadTypeH264; + payload_type = test::VideoTestConstants::kPayloadTypeH264; } else if (params_.video[video_idx].codec == "VP8") { - payload_type = kPayloadTypeVP8; + payload_type = test::VideoTestConstants::kPayloadTypeVP8; } else if (params_.video[video_idx].codec == "VP9") { - payload_type = kPayloadTypeVP9; + payload_type = test::VideoTestConstants::kPayloadTypeVP9; } else if (params_.video[video_idx].codec == "multiplex") { - payload_type = kPayloadTypeVP9; + payload_type = test::VideoTestConstants::kPayloadTypeVP9; } else if (params_.video[video_idx].codec == "FakeCodec") { - payload_type = kFakeVideoSendPayloadType; + payload_type = test::VideoTestConstants::kFakeVideoSendPayloadType; } else { RTC_CHECK(generic_codec_name.empty() || generic_codec_name == params_.video[video_idx].codec) << "Supplying multiple generic codecs is unsupported."; RTC_LOG(LS_INFO) << "Treating codec " << params_.video[video_idx].codec << " as generic."; - payload_type = kPayloadTypeGeneric; + payload_type = test::VideoTestConstants::kPayloadTypeGeneric; generic_codec_name = params_.video[video_idx].codec; } video_send_configs_[video_idx].encoder_settings.encoder_factory = @@ -745,11 +746,13 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, video_send_configs_[video_idx].rtp.payload_name = params_.video[video_idx].codec; video_send_configs_[video_idx].rtp.payload_type = payload_type; - video_send_configs_[video_idx].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - video_send_configs_[video_idx].rtp.rtx.payload_type = kSendRtxPayloadType; + video_send_configs_[video_idx].rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + video_send_configs_[video_idx].rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; for (size_t i = 0; i < num_video_substreams; ++i) { video_send_configs_[video_idx].rtp.rtx.ssrcs.push_back( - kSendRtxSsrcs[i + total_streams_used]); + test::VideoTestConstants::kSendRtxSsrcs[i + total_streams_used]); } video_send_configs_[video_idx].rtp.extensions.clear(); if (params_.call.send_side_bwe) { @@ -824,7 +827,7 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, decode_sub_stream = params_.ss[video_idx].selected_stream; CreateMatchingVideoReceiveConfigs( video_send_configs_[video_idx], recv_transport, &video_decoder_factory_, - decode_sub_stream, true, kNackRtpHistoryMs); + decode_sub_stream, true, test::VideoTestConstants::kNackRtpHistoryMs); if (params_.screenshare[video_idx].enabled) { // Fill out codec settings. @@ -925,7 +928,9 @@ void VideoQualityTest::SetupVideo(Transport* send_transport, if (decode_all_receive_streams) { SetSendFecConfig(GetVideoSendConfig()->rtp.ssrcs); } else { - SetSendFecConfig({kVideoSendSsrcs[params_.ss[0].selected_stream]}); + SetSendFecConfig( + {test::VideoTestConstants::kVideoSendSsrcs[params_.ss[0] + .selected_stream]}); } CreateMatchingFecConfig(recv_transport, *GetVideoSendConfig()); @@ -956,9 +961,12 @@ void VideoQualityTest::SetupThumbnails(Transport* send_transport, thumbnail_send_config.encoder_settings.bitrate_allocator_factory = video_bitrate_allocator_factory_.get(); thumbnail_send_config.rtp.payload_name = params_.video[0].codec; - thumbnail_send_config.rtp.payload_type = kPayloadTypeVP8; - thumbnail_send_config.rtp.nack.rtp_history_ms = kNackRtpHistoryMs; - thumbnail_send_config.rtp.rtx.payload_type = kSendRtxPayloadType; + thumbnail_send_config.rtp.payload_type = + test::VideoTestConstants::kPayloadTypeVP8; + thumbnail_send_config.rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; + thumbnail_send_config.rtp.rtx.payload_type = + test::VideoTestConstants::kSendRtxPayloadType; thumbnail_send_config.rtp.rtx.ssrcs.push_back(kThumbnailRtxSsrcStart + i); thumbnail_send_config.rtp.extensions.clear(); if (params_.call.send_side_bwe) { @@ -988,7 +996,8 @@ void VideoQualityTest::SetupThumbnails(Transport* send_transport, AddMatchingVideoReceiveConfigs( &thumbnail_receive_configs_, thumbnail_send_config, send_transport, - &video_decoder_factory_, absl::nullopt, false, kNackRtpHistoryMs); + &video_decoder_factory_, absl::nullopt, false, + test::VideoTestConstants::kNackRtpHistoryMs); } for (size_t i = 0; i < thumbnail_send_configs_.size(); ++i) { thumbnail_send_streams_.push_back(receiver_call_->CreateVideoSendStream( @@ -1169,11 +1178,12 @@ VideoQualityTest::CreateSendTransport() { return std::make_unique( task_queue(), std::make_unique(clock_, std::move(network_behavior)), - sender_call_.get(), kPayloadTypeVP8, kPayloadTypeVP9, - params_.video[0].selected_tl, params_.ss[0].selected_sl, - payload_type_map_, kVideoSendSsrcs[0], - static_cast(kVideoSendSsrcs[0] + params_.ss[0].streams.size() - - 1), + sender_call_.get(), test::VideoTestConstants::kPayloadTypeVP8, + test::VideoTestConstants::kPayloadTypeVP9, params_.video[0].selected_tl, + params_.ss[0].selected_sl, payload_type_map_, + test::VideoTestConstants::kVideoSendSsrcs[0], + static_cast(test::VideoTestConstants::kVideoSendSsrcs[0] + + params_.ss[0].streams.size() - 1), GetRegisteredExtensions(), GetRegisteredExtensions()); } @@ -1263,8 +1273,8 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) { ? TimeDelta::Millis(1) : TimeDelta::Seconds(params_.analyzer.test_durations_secs), graph_data_output_file, graph_title, - kVideoSendSsrcs[params_.ss[0].selected_stream], - kSendRtxSsrcs[params_.ss[0].selected_stream], + test::VideoTestConstants::kVideoSendSsrcs[params_.ss[0].selected_stream], + test::VideoTestConstants::kSendRtxSsrcs[params_.ss[0].selected_stream], static_cast(params_.ss[0].selected_stream), params.ss[0].selected_sl, params_.video[0].selected_tl, is_quick_test_enabled, clock_, params_.logging.rtp_dump_name, @@ -1393,13 +1403,13 @@ void VideoQualityTest::InitializeAudioDevice(Call::Config* send_call_config, void VideoQualityTest::SetupAudio(Transport* transport) { AudioSendStream::Config audio_send_config(transport); - audio_send_config.rtp.ssrc = kAudioSendSsrc; + audio_send_config.rtp.ssrc = test::VideoTestConstants::kAudioSendSsrc; // Add extension to enable audio send side BWE, and allow audio bit rate // adaptation. audio_send_config.rtp.extensions.clear(); audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec( - kAudioSendPayloadType, + test::VideoTestConstants::kAudioSendPayloadType, {"OPUS", 48000, 2, diff --git a/third_party/libwebrtc/video/video_send_stream.cc b/third_party/libwebrtc/video/video_send_stream.cc index e5545e761cca2..e95ca260a4687 100644 --- a/third_party/libwebrtc/video/video_send_stream.cc +++ b/third_party/libwebrtc/video/video_send_stream.cc @@ -149,8 +149,7 @@ VideoSendStream::VideoSendStream( const std::map& suspended_payload_states, std::unique_ptr fec_controller, const FieldTrialsView& field_trials) - : rtp_transport_queue_(transport->GetWorkerQueue()), - transport_(transport), + : transport_(transport), stats_proxy_(clock, config, encoder_config.content_type, field_trials), config_(std::move(config)), content_type_(encoder_config.content_type), @@ -237,12 +236,7 @@ void VideoSendStream::StartPerRtpStream(const std::vector active_layers) { } active_layers_string << "}"; RTC_LOG(LS_INFO) << "StartPerRtpStream: " << active_layers_string.str(); - - rtp_transport_queue_->RunOrPost( - SafeTask(transport_queue_safety_, [this, active_layers] { - send_stream_.StartPerRtpStream(active_layers); - })); - + send_stream_.StartPerRtpStream(active_layers); running_ = running; } @@ -252,13 +246,7 @@ void VideoSendStream::Stop() { return; RTC_DLOG(LS_INFO) << "VideoSendStream::Stop"; running_ = false; - rtp_transport_queue_->RunOrPost(SafeTask(transport_queue_safety_, [this] { - // As the stream can get re-used and implicitly restarted via changing - // the state of the active layers, we do not mark the - // `transport_queue_safety_` flag with `SetNotAlive()` here. That's only - // done when we stop permanently via `StopPermanentlyAndGetRtpStates()`. - send_stream_.Stop(); - })); + send_stream_.Stop(); } bool VideoSendStream::started() { @@ -300,9 +288,7 @@ void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config, } VideoSendStream::Stats VideoSendStream::GetStats() { - // TODO(perkj, solenberg): Some test cases in EndToEndTest call GetStats from - // a network thread. See comment in Call::GetStats(). - // RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK_RUN_ON(&thread_checker_); return stats_proxy_.GetStats(); } @@ -320,13 +306,9 @@ void VideoSendStream::StopPermanentlyAndGetRtpStates( // Always run these cleanup steps regardless of whether running_ was set // or not. This will unregister callbacks before destruction. // See `VideoSendStreamImpl::StopVideoSendStream` for more. - rtp_transport_queue_->RunSynchronous( - [this, rtp_state_map, payload_state_map]() { - transport_queue_safety_->SetNotAlive(); - send_stream_.Stop(); - *rtp_state_map = send_stream_.GetRtpStates(); - *payload_state_map = send_stream_.GetRtpPayloadStates(); - }); + send_stream_.Stop(); + *rtp_state_map = send_stream_.GetRtpStates(); + *payload_state_map = send_stream_.GetRtpPayloadStates(); } void VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { @@ -335,6 +317,7 @@ void VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { } void VideoSendStream::GenerateKeyFrame(const std::vector& rids) { + RTC_DCHECK_RUN_ON(&thread_checker_); // Map rids to layers. If rids is empty, generate a keyframe for all layers. std::vector next_frames(config_.rtp.ssrcs.size(), VideoFrameType::kVideoFrameKey); diff --git a/third_party/libwebrtc/video/video_send_stream.h b/third_party/libwebrtc/video/video_send_stream.h index 404873fd39bdc..55103ac979ab9 100644 --- a/third_party/libwebrtc/video/video_send_stream.h +++ b/third_party/libwebrtc/video/video_send_stream.h @@ -23,7 +23,6 @@ #include "call/bitrate_allocator.h" #include "call/video_receive_stream.h" #include "call/video_send_stream.h" -#include "modules/utility/maybe_worker_thread.h" #include "rtc_base/event.h" #include "rtc_base/system/no_unique_address.h" #include "video/encoder_rtcp_feedback.h" @@ -103,11 +102,7 @@ class VideoSendStream : public webrtc::VideoSendStream { absl::optional GetPacingFactorOverride() const; RTC_NO_UNIQUE_ADDRESS SequenceChecker thread_checker_; - MaybeWorkerThread* const rtp_transport_queue_; RtpTransportControllerSendInterface* const transport_; - rtc::Event thread_sync_event_; - rtc::scoped_refptr transport_queue_safety_ = - PendingTaskSafetyFlag::CreateDetached(); SendStatisticsProxy stats_proxy_; const VideoSendStream::Config config_; diff --git a/third_party/libwebrtc/video/video_send_stream_impl.cc b/third_party/libwebrtc/video/video_send_stream_impl.cc index 5fa2af398d167..597bf391983fc 100644 --- a/third_party/libwebrtc/video/video_send_stream_impl.cc +++ b/third_party/libwebrtc/video/video_send_stream_impl.cc @@ -233,7 +233,7 @@ VideoSendStreamImpl::VideoSendStreamImpl( pacing_config_(PacingConfig(field_trials)), stats_proxy_(stats_proxy), config_(config), - rtp_transport_queue_(transport->GetWorkerQueue()), + worker_queue_(TaskQueueBase::Current()), timed_out_(false), transport_(transport), bitrate_allocator_(bitrate_allocator), @@ -298,33 +298,26 @@ VideoSendStreamImpl::VideoSendStreamImpl( transport->EnablePeriodicAlrProbing(*enable_alr_bw_probing); } - rtp_transport_queue_->RunOrPost(SafeTask(transport_queue_safety_, [this] { - if (configured_pacing_factor_) - transport_->SetPacingFactor(*configured_pacing_factor_); + if (configured_pacing_factor_) + transport_->SetPacingFactor(*configured_pacing_factor_); - video_stream_encoder_->SetStartBitrate( - bitrate_allocator_->GetStartBitrate(this)); - })); + video_stream_encoder_->SetStartBitrate( + bitrate_allocator_->GetStartBitrate(this)); } VideoSendStreamImpl::~VideoSendStreamImpl() { RTC_DCHECK_RUN_ON(&thread_checker_); RTC_LOG(LS_INFO) << "~VideoSendStreamImpl: " << config_->ToString(); - // TODO(webrtc:14502): Change `transport_queue_safety_` to be of type - // ScopedTaskSafety if experiment WebRTC-SendPacketsOnWorkerThread succeed. - if (rtp_transport_queue_->IsCurrent()) { - transport_queue_safety_->SetNotAlive(); - } } void VideoSendStreamImpl::DeliverRtcp(const uint8_t* packet, size_t length) { - // Runs on a worker thread. + RTC_DCHECK_RUN_ON(&thread_checker_); rtp_video_sender_->DeliverRtcp(packet, length); } void VideoSendStreamImpl::StartPerRtpStream( const std::vector active_layers) { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); bool previously_active = rtp_video_sender_->IsActive(); rtp_video_sender_->SetActiveModules(active_layers); if (!rtp_video_sender_->IsActive() && previously_active) { @@ -335,8 +328,7 @@ void VideoSendStreamImpl::StartPerRtpStream( } void VideoSendStreamImpl::StartupVideoSendStream() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); - transport_queue_safety_->SetAlive(); + RTC_DCHECK_RUN_ON(&thread_checker_); bitrate_allocator_->AddObserver(this, GetAllocationConfig()); // Start monitoring encoder activity. @@ -346,9 +338,8 @@ void VideoSendStreamImpl::StartupVideoSendStream() { activity_ = false; timed_out_ = false; check_encoder_activity_task_ = RepeatingTaskHandle::DelayedStart( - rtp_transport_queue_->TaskQueueForDelayedTasks(), kEncoderTimeOut, - [this] { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + worker_queue_, kEncoderTimeOut, [this] { + RTC_DCHECK_RUN_ON(&thread_checker_); if (!activity_) { if (!timed_out_) { SignalEncoderTimedOut(); @@ -368,29 +359,27 @@ void VideoSendStreamImpl::StartupVideoSendStream() { } void VideoSendStreamImpl::Stop() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_LOG(LS_INFO) << "VideoSendStreamImpl::Stop"; if (!rtp_video_sender_->IsActive()) return; - RTC_DCHECK(transport_queue_safety_->alive()); TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); rtp_video_sender_->Stop(); StopVideoSendStream(); } void VideoSendStreamImpl::StopVideoSendStream() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); bitrate_allocator_->RemoveObserver(this); check_encoder_activity_task_.Stop(); video_stream_encoder_->OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), DataRate::Zero(), 0, 0, 0); stats_proxy_->OnSetEncoderTargetRate(0); - transport_queue_safety_->SetNotAlive(); } void VideoSendStreamImpl::SignalEncoderTimedOut() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); // If the encoder has not produced anything the last kEncoderTimeOut and it // is supposed to, deregister as BitrateAllocatorObserver. This can happen // if a camera stops producing frames. @@ -403,9 +392,9 @@ void VideoSendStreamImpl::SignalEncoderTimedOut() { void VideoSendStreamImpl::OnBitrateAllocationUpdated( const VideoBitrateAllocation& allocation) { // OnBitrateAllocationUpdated is invoked from the encoder task queue or - // the rtp_transport_queue_. - auto task = [=] { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + // the worker_queue_. + auto task = [this, allocation] { + RTC_DCHECK_RUN_ON(&thread_checker_); if (encoder_target_rate_bps_ == 0) { return; } @@ -441,9 +430,9 @@ void VideoSendStreamImpl::OnBitrateAllocationUpdated( // Send bitrate allocation metadata only if encoder is not paused. rtp_video_sender_->OnBitrateAllocationUpdated(allocation); }; - if (!rtp_transport_queue_->IsCurrent()) { - rtp_transport_queue_->TaskQueueForPost()->PostTask( - SafeTask(transport_queue_safety_, std::move(task))); + if (!worker_queue_->IsCurrent()) { + worker_queue_->PostTask( + SafeTask(worker_queue_safety_.flag(), std::move(task))); } else { task(); } @@ -457,7 +446,7 @@ void VideoSendStreamImpl::OnVideoLayersAllocationUpdated( } void VideoSendStreamImpl::SignalEncoderActive() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); if (rtp_video_sender_->IsActive()) { RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active."; bitrate_allocator_->AddObserver(this, GetAllocationConfig()); @@ -480,12 +469,12 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( VideoEncoderConfig::ContentType content_type, int min_transmit_bitrate_bps) { // Currently called on the encoder TQ - RTC_DCHECK(!rtp_transport_queue_->IsCurrent()); + RTC_DCHECK(!worker_queue_->IsCurrent()); auto closure = [this, streams = std::move(streams), is_svc, content_type, min_transmit_bitrate_bps]() mutable { RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size()); TRACE_EVENT0("webrtc", "VideoSendStream::OnEncoderConfigurationChanged"); - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); const VideoCodecType codec_type = PayloadStringToCodecType(config_->rtp.payload_name); @@ -537,8 +526,8 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( } }; - rtp_transport_queue_->TaskQueueForPost()->PostTask( - SafeTask(transport_queue_safety_, std::move(closure))); + worker_queue_->PostTask( + SafeTask(worker_queue_safety_.flag(), std::move(closure))); } EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage( @@ -550,10 +539,10 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage( // Indicate that there still is activity going on. activity_ = true; - RTC_DCHECK(!rtp_transport_queue_->IsCurrent()); + RTC_DCHECK(!worker_queue_->IsCurrent()); auto task_to_run_on_worker = [this]() { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); if (disable_padding_) { disable_padding_ = false; // To ensure that padding bitrate is propagated to the bitrate allocator. @@ -566,8 +555,8 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage( OnBitrateAllocationUpdated(*context->throttled_allocation); } }; - rtp_transport_queue_->TaskQueueForPost()->PostTask( - SafeTask(transport_queue_safety_, std::move(task_to_run_on_worker))); + worker_queue_->PostTask( + SafeTask(worker_queue_safety_.flag(), std::move(task_to_run_on_worker))); return rtp_video_sender_->OnEncodedImage(encoded_image, codec_specific_info); } @@ -587,7 +576,7 @@ std::map VideoSendStreamImpl::GetRtpPayloadStates() } uint32_t VideoSendStreamImpl::OnBitrateUpdated(BitrateAllocationUpdate update) { - RTC_DCHECK_RUN_ON(rtp_transport_queue_); + RTC_DCHECK_RUN_ON(&thread_checker_); RTC_DCHECK(rtp_video_sender_->IsActive()) << "VideoSendStream::Start has not been called."; diff --git a/third_party/libwebrtc/video/video_send_stream_impl.h b/third_party/libwebrtc/video/video_send_stream_impl.h index f1454506555a4..f202b573427a4 100644 --- a/third_party/libwebrtc/video/video_send_stream_impl.h +++ b/third_party/libwebrtc/video/video_send_stream_impl.h @@ -32,7 +32,6 @@ #include "call/rtp_video_sender_interface.h" #include "modules/include/module_common_types.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" -#include "modules/utility/maybe_worker_thread.h" #include "modules/video_coding/include/video_codec_interface.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/system/no_unique_address.h" @@ -121,14 +120,14 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver, void StartupVideoSendStream(); // Removes the bitrate observer, stops monitoring and notifies the video // encoder of the bitrate update. - void StopVideoSendStream() RTC_RUN_ON(rtp_transport_queue_); + void StopVideoSendStream() RTC_RUN_ON(thread_checker_); void ConfigureProtection(); void ConfigureSsrcs(); void SignalEncoderTimedOut(); void SignalEncoderActive(); MediaStreamAllocationConfig GetAllocationConfig() const - RTC_RUN_ON(rtp_transport_queue_); + RTC_RUN_ON(thread_checker_); RTC_NO_UNIQUE_ADDRESS SequenceChecker thread_checker_; Clock* const clock_; @@ -138,31 +137,30 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver, SendStatisticsProxy* const stats_proxy_; const VideoSendStream::Config* const config_; - MaybeWorkerThread* const rtp_transport_queue_; + TaskQueueBase* const worker_queue_; RepeatingTaskHandle check_encoder_activity_task_ - RTC_GUARDED_BY(rtp_transport_queue_); + RTC_GUARDED_BY(thread_checker_); std::atomic_bool activity_; - bool timed_out_ RTC_GUARDED_BY(rtp_transport_queue_); + bool timed_out_ RTC_GUARDED_BY(thread_checker_); RtpTransportControllerSendInterface* const transport_; BitrateAllocatorInterface* const bitrate_allocator_; - bool disable_padding_; - int max_padding_bitrate_; - int encoder_min_bitrate_bps_; - uint32_t encoder_max_bitrate_bps_; - uint32_t encoder_target_rate_bps_; - double encoder_bitrate_priority_; + 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_); + uint32_t encoder_max_bitrate_bps_ RTC_GUARDED_BY(thread_checker_); + uint32_t encoder_target_rate_bps_ RTC_GUARDED_BY(thread_checker_); + double encoder_bitrate_priority_ RTC_GUARDED_BY(thread_checker_); VideoStreamEncoderInterface* const video_stream_encoder_; RtcpBandwidthObserver* const bandwidth_observer_; RtpVideoSenderInterface* const rtp_video_sender_; - rtc::scoped_refptr transport_queue_safety_ = - PendingTaskSafetyFlag::CreateDetached(); + ScopedTaskSafety worker_queue_safety_; // Context for the most recent and last sent video bitrate allocation. Used to // throttle sending of similar bitrate allocations. @@ -172,7 +170,7 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver, int64_t last_send_time_ms; }; absl::optional video_bitrate_allocation_context_ - RTC_GUARDED_BY(rtp_transport_queue_); + RTC_GUARDED_BY(thread_checker_); const absl::optional configured_pacing_factor_; }; } // namespace internal diff --git a/third_party/libwebrtc/video/video_send_stream_impl_unittest.cc b/third_party/libwebrtc/video/video_send_stream_impl_unittest.cc index 0fcc5e44cc596..c88ad06cfb416 100644 --- a/third_party/libwebrtc/video/video_send_stream_impl_unittest.cc +++ b/third_party/libwebrtc/video/video_send_stream_impl_unittest.cc @@ -24,7 +24,6 @@ #include "call/test/mock_bitrate_allocator.h" #include "call/test/mock_rtp_transport_controller_send.h" #include "modules/rtp_rtcp/source/rtp_sequence_number_map.h" -#include "modules/utility/maybe_worker_thread.h" #include "modules/video_coding/fec_controller_default.h" #include "rtc_base/event.h" #include "rtc_base/experiments/alr_experiment.h" @@ -123,9 +122,6 @@ class VideoSendStreamImplTest : public ::testing::Test { : time_controller_(Timestamp::Seconds(1000)), config_(&transport_), send_delay_stats_(time_controller_.GetClock()), - worker_queue_(field_trials_, - "worker_queue", - time_controller_.GetTaskQueueFactory()), encoder_queue_(time_controller_.GetTaskQueueFactory()->CreateTaskQueue( "encoder_queue", TaskQueueFactory::Priority::NORMAL)), @@ -153,8 +149,6 @@ class VideoSendStreamImplTest : public ::testing::Test { })); ON_CALL(rtp_video_sender_, SetActiveModules) .WillByDefault(::testing::SaveArg<0>(&active_modules_)); - ON_CALL(transport_controller_, GetWorkerQueue()) - .WillByDefault(Return(&worker_queue_)); } ~VideoSendStreamImplTest() {} @@ -162,8 +156,6 @@ class VideoSendStreamImplTest : public ::testing::Test { int initial_encoder_max_bitrate, double initial_encoder_bitrate_priority, VideoEncoderConfig::ContentType content_type) { - RTC_DCHECK_RUN_ON(&worker_queue_); - EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_)) .WillOnce(Return(123000)); @@ -196,7 +188,6 @@ class VideoSendStreamImplTest : public ::testing::Test { RtcEventLogNull event_log_; VideoSendStream::Config config_; SendDelayStats send_delay_stats_; - MaybeWorkerThread worker_queue_; std::unique_ptr encoder_queue_; SendStatisticsProxy stats_proxy_; PacketRouter packet_router_; @@ -217,11 +208,9 @@ TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) { EXPECT_EQ(config.enforce_min_bitrate, !kSuspend); EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority); })); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); - vss_impl->Stop(); - }); + vss_impl->StartPerRtpStream({true}); + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { @@ -233,7 +222,7 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kRealtimeVideo); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // QVGA + VGA configuration matching defaults in // media/engine/simulcast.cc. @@ -265,7 +254,6 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) .WillRepeatedly(Invoke( [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { - EXPECT_TRUE(worker_queue_.IsCurrent()); EXPECT_EQ(config.min_bitrate_bps, static_cast(min_transmit_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -287,7 +275,7 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { min_transmit_bitrate_bps); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { @@ -299,7 +287,7 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // Simulcast screenshare. VideoStream low_stream; @@ -334,7 +322,6 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) .WillRepeatedly(Invoke( [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { - EXPECT_TRUE(worker_queue_.IsCurrent()); EXPECT_EQ(config.min_bitrate_bps, static_cast(low_stream.min_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -353,7 +340,7 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { VideoEncoderConfig::ContentType::kScreen, min_transmit_bitrate_bps); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, @@ -365,7 +352,7 @@ TEST_F(VideoSendStreamImplTest, kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kRealtimeVideo); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // 2-layer video simulcast. VideoStream low_stream; low_stream.width = 320; @@ -393,7 +380,6 @@ TEST_F(VideoSendStreamImplTest, EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) .WillRepeatedly(Invoke([&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { - EXPECT_TRUE(worker_queue_.IsCurrent()); EXPECT_EQ(config.min_bitrate_bps, static_cast(low_stream.min_bitrate_bps)); EXPECT_EQ(config.max_bitrate_bps, @@ -414,7 +400,7 @@ TEST_F(VideoSendStreamImplTest, /*min_transmit_bitrate_bps=*/0); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) { @@ -429,10 +415,8 @@ TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - vss_impl->Stop(); - }); + vss_impl->StartPerRtpStream({true}); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) { @@ -440,11 +424,9 @@ TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { - EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); - vss_impl->StartPerRtpStream({true}); - vss_impl->Stop(); - }); + EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); + vss_impl->StartPerRtpStream({true}); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { @@ -455,7 +437,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); VideoStreamEncoderInterface::EncoderSink* const sink = static_cast(vss_impl.get()); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // Populate a test instance of video bitrate allocation. VideoBitrateAllocation alloc; alloc.SetBitrate(0, 0, 10000); @@ -471,46 +453,40 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { - // Unpause encoder, allocation should be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + // Unpause encoder, allocation should be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(1); encoder_queue_->PostTask([&] { sink->OnBitrateAllocationUpdated(alloc); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { - // Pause encoder again, and block allocations. - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(0)); - }); + // Pause encoder again, and block allocations. + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(0)); EXPECT_CALL(rtp_video_sender_, OnBitrateAllocationUpdated(alloc)).Times(0); encoder_queue_->PostTask([&] { sink->OnBitrateAllocationUpdated(alloc); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - // Unpause encoder, to allows allocations to be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + vss_impl->StartPerRtpStream({true}); + // Unpause encoder, to allows allocations to be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); VideoStreamEncoderInterface::EncoderSink* const sink = static_cast(vss_impl.get()); @@ -555,7 +531,7 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { [&] { sink->OnBitrateAllocationUpdated(updated_alloc); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { @@ -563,16 +539,14 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - // Unpause encoder, to allows allocations to be passed through. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + vss_impl->StartPerRtpStream({true}); + // Unpause encoder, to allows allocations to be passed through. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); VideoStreamEncoderInterface::EncoderSink* const sink = static_cast(vss_impl.get()); @@ -599,23 +573,21 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { [&] { sink->OnBitrateAllocationUpdated(updated_alloc); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kScreen); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - const uint32_t kBitrateBps = 100000; - // Unpause encoder, to allows allocations to be passed through. - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillRepeatedly(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + vss_impl->StartPerRtpStream({true}); + const uint32_t kBitrateBps = 100000; + // Unpause encoder, to allows allocations to be passed through. + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillRepeatedly(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); VideoStreamEncoderInterface::EncoderSink* const sink = static_cast(vss_impl.get()); @@ -706,7 +678,7 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { time_controller_.AdvanceTime(TimeDelta::Zero()); } - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { @@ -717,7 +689,7 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { auto vss_impl = CreateVideoSendStreamImpl( kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kRealtimeVideo); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); VideoStream qvga_stream; qvga_stream.width = 320; qvga_stream.height = 180; @@ -741,76 +713,74 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { }); time_controller_.AdvanceTime(TimeDelta::Zero()); - worker_queue_.RunSynchronous([&] { - const DataRate network_constrained_rate = - DataRate::BitsPerSec(qvga_stream.target_bitrate_bps); - BitrateAllocationUpdate update; - update.target_bitrate = network_constrained_rate; - update.stable_target_bitrate = network_constrained_rate; - update.round_trip_time = TimeDelta::Millis(1); - EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(network_constrained_rate.bps())); - EXPECT_CALL( - video_stream_encoder_, - OnBitrateUpdated(network_constrained_rate, network_constrained_rate, - network_constrained_rate, 0, _, 0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); - - // Test allocation where the link allocation is larger than the - // target, meaning we have some headroom on the link. - const DataRate qvga_max_bitrate = - DataRate::BitsPerSec(qvga_stream.max_bitrate_bps); - const DataRate headroom = DataRate::BitsPerSec(50000); - const DataRate rate_with_headroom = qvga_max_bitrate + headroom; - update.target_bitrate = rate_with_headroom; - update.stable_target_bitrate = rate_with_headroom; - EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - rate_with_headroom, 0, _, 0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); - - // Add protection bitrate to the mix, this should be subtracted - // from the headroom. - const uint32_t protection_bitrate_bps = 10000; - EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) - .WillOnce(Return(protection_bitrate_bps)); - - EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - const DataRate headroom_minus_protection = - rate_with_headroom - DataRate::BitsPerSec(protection_bitrate_bps); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - headroom_minus_protection, 0, _, 0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); - - // Protection bitrate exceeds head room, link allocation should be - // capped to target bitrate. - EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) - .WillOnce(Return(headroom.bps() + 1000)); - EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .WillOnce(Return(rate_with_headroom.bps())); - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, - qvga_max_bitrate, 0, _, 0)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(update); - - // Set rates to zero on stop. - EXPECT_CALL(video_stream_encoder_, - OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), - DataRate::Zero(), 0, 0, 0)); - vss_impl->Stop(); - }); + const DataRate network_constrained_rate = + DataRate::BitsPerSec(qvga_stream.target_bitrate_bps); + BitrateAllocationUpdate update; + update.target_bitrate = network_constrained_rate; + update.stable_target_bitrate = network_constrained_rate; + update.round_trip_time = TimeDelta::Millis(1); + EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(network_constrained_rate.bps())); + EXPECT_CALL( + video_stream_encoder_, + OnBitrateUpdated(network_constrained_rate, network_constrained_rate, + network_constrained_rate, 0, _, 0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); + + // Test allocation where the link allocation is larger than the + // target, meaning we have some headroom on the link. + const DataRate qvga_max_bitrate = + DataRate::BitsPerSec(qvga_stream.max_bitrate_bps); + const DataRate headroom = DataRate::BitsPerSec(50000); + const DataRate rate_with_headroom = qvga_max_bitrate + headroom; + update.target_bitrate = rate_with_headroom; + update.stable_target_bitrate = rate_with_headroom; + EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + rate_with_headroom, 0, _, 0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); + + // Add protection bitrate to the mix, this should be subtracted + // from the headroom. + const uint32_t protection_bitrate_bps = 10000; + EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) + .WillOnce(Return(protection_bitrate_bps)); + + EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + const DataRate headroom_minus_protection = + rate_with_headroom - DataRate::BitsPerSec(protection_bitrate_bps); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + headroom_minus_protection, 0, _, 0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); + + // Protection bitrate exceeds head room, link allocation should be + // capped to target bitrate. + EXPECT_CALL(rtp_video_sender_, GetProtectionBitrateBps()) + .WillOnce(Return(headroom.bps() + 1000)); + EXPECT_CALL(rtp_video_sender_, OnBitrateUpdated(update, _)); + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .WillOnce(Return(rate_with_headroom.bps())); + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(qvga_max_bitrate, qvga_max_bitrate, + qvga_max_bitrate, 0, _, 0)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(update); + + // Set rates to zero on stop. + EXPECT_CALL(video_stream_encoder_, + OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(), + DataRate::Zero(), 0, 0, 0)); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { @@ -850,7 +820,7 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { int min_transmit_bitrate_bps = 30000; config_.rtp.ssrcs.emplace_back(1); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // Starts without padding. EXPECT_EQ(0, padding_bitrate); encoder_queue_->PostTask([&] { @@ -866,15 +836,13 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { // reconfiguration happened. EXPECT_EQ(0, padding_bitrate); - worker_queue_.RunSynchronous([&] { - // Unpause encoder. - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + // Unpause encoder. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); encoder_queue_->PostTask([&] { // A frame is encoded. @@ -892,7 +860,7 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { // sent. EXPECT_EQ(0, padding_bitrate); testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) { @@ -900,25 +868,21 @@ TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) { kDefaultInitialBitrateBps, kDefaultBitratePriority, VideoEncoderConfig::ContentType::kRealtimeVideo); EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(0); - worker_queue_.RunSynchronous([&] { - vss_impl->StartPerRtpStream({true}); - const uint32_t kBitrateBps = 100000; - EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) - .Times(1) - .WillOnce(Return(kBitrateBps)); - static_cast(vss_impl.get()) - ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); - }); + vss_impl->StartPerRtpStream({true}); + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); encoder_queue_->PostTask([&] { // Keep the stream from deallocating by dropping a frame. static_cast(vss_impl.get()) ->OnDroppedFrame(EncodedImageCallback::DropReason::kDroppedByEncoder); }); time_controller_.AdvanceTime(TimeDelta::Seconds(2)); - worker_queue_.RunSynchronous([&] { - testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); - vss_impl->Stop(); - }); + testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); + vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) { @@ -949,7 +913,7 @@ TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) { ? VideoEncoderConfig::ContentType::kScreen : VideoEncoderConfig::ContentType::kRealtimeVideo); - worker_queue_.RunSynchronous([&] { vss_impl->StartPerRtpStream({true}); }); + vss_impl->StartPerRtpStream({true}); // Svc VideoStream stream; @@ -1030,7 +994,7 @@ TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) { time_controller_.AdvanceTime(TimeDelta::Zero()); ::testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); - worker_queue_.RunSynchronous([&] { vss_impl->Stop(); }); + vss_impl->Stop(); } } } // namespace internal diff --git a/third_party/libwebrtc/video/video_send_stream_tests.cc b/third_party/libwebrtc/video/video_send_stream_tests.cc index 4e1fefef101b9..cb24993ac894d 100644 --- a/third_party/libwebrtc/video/video_send_stream_tests.cc +++ b/third_party/libwebrtc/video/video_send_stream_tests.cc @@ -71,6 +71,7 @@ #include "test/rtcp_packet_parser.h" #include "test/rtp_rtcp_observer.h" #include "test/video_encoder_proxy_factory.h" +#include "test/video_test_constants.h" #include "video/config/encoder_stream_factory.h" #include "video/send_statistics_proxy.h" #include "video/transport_adapter.h" @@ -186,7 +187,7 @@ TEST_F(VideoSendStreamTest, SupportsCName) { static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; class CNameObserver : public test::SendTest { public: - CNameObserver() : SendTest(kDefaultTimeout) {} + CNameObserver() : SendTest(test::VideoTestConstants::kDefaultTimeout) {} private: Action OnSendRtcp(const uint8_t* packet, size_t length) override { @@ -220,7 +221,8 @@ TEST_F(VideoSendStreamTest, SupportsCName) { TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { class AbsoluteSendTimeObserver : public test::SendTest { public: - AbsoluteSendTimeObserver() : SendTest(kDefaultTimeout) { + AbsoluteSendTimeObserver() + : SendTest(test::VideoTestConstants::kDefaultTimeout) { extensions_.Register(kAbsSendTimeExtensionId); } @@ -271,7 +273,8 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { class TransmissionTimeOffsetObserver : public test::SendTest { public: TransmissionTimeOffsetObserver() - : SendTest(kDefaultTimeout), encoder_factory_([]() { + : SendTest(test::VideoTestConstants::kDefaultTimeout), + encoder_factory_([]() { return std::make_unique( Clock::GetRealTimeClock(), kEncodeDelayMs); }) { @@ -318,7 +321,8 @@ TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) { class TransportWideSequenceNumberObserver : public test::SendTest { public: TransportWideSequenceNumberObserver() - : SendTest(kDefaultTimeout), encoder_factory_([]() { + : SendTest(test::VideoTestConstants::kDefaultTimeout), + encoder_factory_([]() { return std::make_unique( Clock::GetRealTimeClock()); }) { @@ -360,7 +364,8 @@ TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) { TEST_F(VideoSendStreamTest, SupportsVideoRotation) { class VideoRotationObserver : public test::SendTest { public: - VideoRotationObserver() : SendTest(kDefaultTimeout) { + VideoRotationObserver() + : SendTest(test::VideoTestConstants::kDefaultTimeout) { extensions_.Register(kVideoRotationExtensionId); } @@ -404,7 +409,8 @@ TEST_F(VideoSendStreamTest, SupportsVideoContentType) { class VideoContentTypeObserver : public test::SendTest { public: VideoContentTypeObserver() - : SendTest(kDefaultTimeout), first_frame_sent_(false) { + : SendTest(test::VideoTestConstants::kDefaultTimeout), + first_frame_sent_(false) { extensions_.Register( kVideoContentTypeExtensionId); } @@ -450,7 +456,8 @@ TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) { class VideoTimingObserver : public test::SendTest { public: VideoTimingObserver() - : SendTest(kDefaultTimeout), first_frame_sent_(false) { + : SendTest(test::VideoTestConstants::kDefaultTimeout), + first_frame_sent_(false) { extensions_.Register(kVideoTimingExtensionId); } @@ -522,7 +529,7 @@ class UlpfecObserver : public test::EndToEndTest { bool expect_ulpfec, const std::string& codec, VideoEncoderFactory* encoder_factory) - : EndToEndTest(expect_ulpfec ? VideoSendStreamTest::kDefaultTimeout + : EndToEndTest(expect_ulpfec ? test::VideoTestConstants::kDefaultTimeout : kReducedTimeout), encoder_factory_(encoder_factory), payload_name_(codec), @@ -543,16 +550,16 @@ class UlpfecObserver : public test::EndToEndTest { EXPECT_TRUE(rtp_packet.Parse(packet, length)); int encapsulated_payload_type = -1; - if (rtp_packet.PayloadType() == VideoSendStreamTest::kRedPayloadType) { + if (rtp_packet.PayloadType() == test::VideoTestConstants::kRedPayloadType) { EXPECT_TRUE(expect_red_); encapsulated_payload_type = rtp_packet.payload()[0]; if (encapsulated_payload_type != - VideoSendStreamTest::kFakeVideoSendPayloadType) { - EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType, + test::VideoTestConstants::kFakeVideoSendPayloadType) { + EXPECT_EQ(test::VideoTestConstants::kUlpfecPayloadType, encapsulated_payload_type); } } else { - EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType, + EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType, rtp_packet.PayloadType()); if (rtp_packet.payload_size() > 0) { // Not padding-only, media received outside of RED. @@ -587,7 +594,7 @@ class UlpfecObserver : public test::EndToEndTest { if (encapsulated_payload_type != -1) { if (encapsulated_payload_type == - VideoSendStreamTest::kUlpfecPayloadType) { + test::VideoTestConstants::kUlpfecPayloadType) { EXPECT_TRUE(expect_ulpfec_); sent_ulpfec_ = true; } else { @@ -619,14 +626,14 @@ class UlpfecObserver : public test::EndToEndTest { if (use_nack_) { send_config->rtp.nack.rtp_history_ms = (*receive_configs)[0].rtp.nack.rtp_history_ms = - VideoSendStreamTest::kNackRtpHistoryMs; + test::VideoTestConstants::kNackRtpHistoryMs; } send_config->encoder_settings.encoder_factory = encoder_factory_; send_config->rtp.payload_name = payload_name_; send_config->rtp.ulpfec.red_payload_type = - VideoSendStreamTest::kRedPayloadType; + test::VideoTestConstants::kRedPayloadType; send_config->rtp.ulpfec.ulpfec_payload_type = - VideoSendStreamTest::kUlpfecPayloadType; + test::VideoTestConstants::kUlpfecPayloadType; if (!header_extensions_enabled_) { send_config->rtp.extensions.clear(); } else { @@ -746,7 +753,7 @@ class FlexfecObserver : public test::EndToEndTest { const std::string& codec, VideoEncoderFactory* encoder_factory, size_t num_video_streams) - : EndToEndTest(VideoSendStreamTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), encoder_factory_(encoder_factory), payload_name_(codec), use_nack_(use_nack), @@ -768,15 +775,17 @@ class FlexfecObserver : public test::EndToEndTest { RtpPacket rtp_packet(&extensions_); EXPECT_TRUE(rtp_packet.Parse(packet, length)); - if (rtp_packet.PayloadType() == VideoSendStreamTest::kFlexfecPayloadType) { - EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, rtp_packet.Ssrc()); + if (rtp_packet.PayloadType() == + test::VideoTestConstants::kFlexfecPayloadType) { + EXPECT_EQ(test::VideoTestConstants::kFlexfecSendSsrc, rtp_packet.Ssrc()); sent_flexfec_ = true; } else { - EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType, + EXPECT_EQ(test::VideoTestConstants::kFakeVideoSendPayloadType, rtp_packet.PayloadType()); - EXPECT_THAT(::testing::make_tuple(VideoSendStreamTest::kVideoSendSsrcs, - num_video_streams_), - ::testing::Contains(rtp_packet.Ssrc())); + EXPECT_THAT( + ::testing::make_tuple(test::VideoTestConstants::kVideoSendSsrcs, + num_video_streams_), + ::testing::Contains(rtp_packet.Ssrc())); sent_media_ = true; } @@ -819,7 +828,7 @@ class FlexfecObserver : public test::EndToEndTest { if (use_nack_) { send_config->rtp.nack.rtp_history_ms = (*receive_configs)[0].rtp.nack.rtp_history_ms = - VideoSendStreamTest::kNackRtpHistoryMs; + test::VideoTestConstants::kNackRtpHistoryMs; } send_config->encoder_settings.encoder_factory = encoder_factory_; send_config->rtp.payload_name = payload_name_; @@ -928,7 +937,7 @@ void VideoSendStreamTest::TestNackRetransmission( public: explicit NackObserver(uint32_t retransmit_ssrc, uint8_t retransmit_payload_type) - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), send_count_(0), retransmit_count_(0), retransmit_ssrc_(retransmit_ssrc), @@ -956,11 +965,12 @@ void VideoSendStreamTest::TestNackRetransmission( config.clock = Clock::GetRealTimeClock(); config.outgoing_transport = transport_adapter_.get(); config.rtcp_report_interval = TimeDelta::Millis(kRtcpIntervalMs); - config.local_media_ssrc = kReceiverLocalVideoSsrc; + config.local_media_ssrc = + test::VideoTestConstants::kReceiverLocalVideoSsrc; RTCPSender rtcp_sender(config); rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize); - rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]); + rtcp_sender.SetRemoteSSRC(test::VideoTestConstants::kVideoSendSsrcs[0]); RTCPSender::FeedbackState feedback_state; uint16_t nack_sequence_numbers[kNackedPacketsAtOnceCount]; @@ -980,7 +990,7 @@ void VideoSendStreamTest::TestNackRetransmission( uint16_t sequence_number = rtp_packet.SequenceNumber(); if (rtp_packet.Ssrc() == retransmit_ssrc_ && - retransmit_ssrc_ != kVideoSendSsrcs[0]) { + retransmit_ssrc_ != test::VideoTestConstants::kVideoSendSsrcs[0]) { // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence // number. const uint8_t* rtx_header = rtp_packet.payload().data(); @@ -991,7 +1001,7 @@ void VideoSendStreamTest::TestNackRetransmission( if (it == sequence_numbers_pending_retransmission_.end()) { // Not currently pending retransmission. Add it to retransmission queue // if media and limit not reached. - if (rtp_packet.Ssrc() == kVideoSendSsrcs[0] && + if (rtp_packet.Ssrc() == test::VideoTestConstants::kVideoSendSsrcs[0] && rtp_packet.payload_size() > 0 && retransmit_count_ + sequence_numbers_pending_retransmission_.size() < @@ -1019,9 +1029,10 @@ void VideoSendStreamTest::TestNackRetransmission( transport_adapter_.reset( new internal::TransportAdapter(send_config->send_transport)); transport_adapter_->Enable(); - send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; + send_config->rtp.nack.rtp_history_ms = + test::VideoTestConstants::kNackRtpHistoryMs; send_config->rtp.rtx.payload_type = retransmit_payload_type_; - if (retransmit_ssrc_ != kVideoSendSsrcs[0]) + if (retransmit_ssrc_ != test::VideoTestConstants::kVideoSendSsrcs[0]) send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_); } @@ -1042,12 +1053,14 @@ void VideoSendStreamTest::TestNackRetransmission( TEST_F(VideoSendStreamTest, RetransmitsNack) { // Normal NACKs should use the send SSRC. - TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType); + TestNackRetransmission(test::VideoTestConstants::kVideoSendSsrcs[0], + test::VideoTestConstants::kFakeVideoSendPayloadType); } TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) { // NACKs over RTX should use a separate SSRC. - TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType); + TestNackRetransmission(test::VideoTestConstants::kSendRtxSsrcs[0], + test::VideoTestConstants::kSendRtxPayloadType); } void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, @@ -1068,7 +1081,7 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, size_t stop_size, bool test_generic_packetization, bool use_fec) - : SendTest(kLongTimeout), + : SendTest(test::VideoTestConstants::kLongTimeout), encoder_(stop), encoder_factory_(&encoder_), max_packet_size_(max_packet_size), @@ -1101,8 +1114,10 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, if (use_fec_ && rtp_packet.payload_size() > 0) { uint8_t payload_type = rtp_packet.payload()[0]; - bool is_fec = rtp_packet.PayloadType() == kRedPayloadType && - payload_type == kUlpfecPayloadType; + bool is_fec = + rtp_packet.PayloadType() == + test::VideoTestConstants::kRedPayloadType && + payload_type == test::VideoTestConstants::kUlpfecPayloadType; if (is_fec) { fec_packet_received_ = true; return SEND_PACKET; @@ -1181,7 +1196,8 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, uint8_t loss_ratio = static_cast(loss_delta * 255 / packets_delta); FakeReceiveStatistics lossy_receive_stats( - kVideoSendSsrcs[0], rtp_packet.SequenceNumber(), + test::VideoTestConstants::kVideoSendSsrcs[0], + rtp_packet.SequenceNumber(), packets_lost_, // Cumulative lost. loss_ratio); // Loss percent. RTCPSender::Configuration config; @@ -1189,11 +1205,11 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, config.receive_statistics = &lossy_receive_stats; config.outgoing_transport = transport_adapter_.get(); config.rtcp_report_interval = TimeDelta::Millis(kRtcpIntervalMs); - config.local_media_ssrc = kVideoSendSsrcs[0]; + config.local_media_ssrc = test::VideoTestConstants::kVideoSendSsrcs[0]; RTCPSender rtcp_sender(config); rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize); - rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]); + rtcp_sender.SetRemoteSSRC(test::VideoTestConstants::kVideoSendSsrcs[0]); RTCPSender::FeedbackState feedback_state; @@ -1224,8 +1240,10 @@ void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, new internal::TransportAdapter(send_config->send_transport)); transport_adapter_->Enable(); if (use_fec_) { - send_config->rtp.ulpfec.red_payload_type = kRedPayloadType; - send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType; + send_config->rtp.ulpfec.red_payload_type = + test::VideoTestConstants::kRedPayloadType; + send_config->rtp.ulpfec.ulpfec_payload_type = + test::VideoTestConstants::kUlpfecPayloadType; } if (!test_generic_packetization_) @@ -1302,7 +1320,7 @@ TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { class NoPaddingWhenVideoIsMuted : public test::SendTest { public: NoPaddingWhenVideoIsMuted() - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), clock_(Clock::GetRealTimeClock()), capturer_(nullptr) {} @@ -1391,7 +1409,7 @@ TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) { class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest { public: PaddingIsPrimarilyRetransmissions() - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), clock_(Clock::GetRealTimeClock()), padding_length_(0), total_length_(0), @@ -1426,8 +1444,10 @@ TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) { std::vector* receive_configs, VideoEncoderConfig* encoder_config) override { // Turn on RTX. - send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType; - send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); + send_config->rtp.rtx.payload_type = + test::VideoTestConstants::kFakeVideoSendPayloadType; + send_config->rtp.rtx.ssrcs.push_back( + test::VideoTestConstants::kSendRtxSsrcs[0]); } void PerformTest() override { @@ -1467,7 +1487,7 @@ TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { class BitrateObserver : public test::SendTest { public: explicit BitrateObserver(TaskQueueBase* task_queue) - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), task_queue_(task_queue), retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000), stream_(nullptr), @@ -1560,7 +1580,7 @@ TEST_F(VideoSendStreamTest, ChangingNetworkRoute) { class ChangingNetworkRouteTest : public test::EndToEndTest { public: explicit ChangingNetworkRouteTest(TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), task_queue_(task_queue), call_(nullptr) { module_process_thread_.Detach(); @@ -1680,7 +1700,7 @@ TEST_F(VideoSendStreamTest, DISABLED_RelayToDirectRoute) { class RelayToDirectRouteTest : public test::EndToEndTest { public: explicit RelayToDirectRouteTest(TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), task_queue_(task_queue), call_(nullptr), packets_sent_(0), @@ -1775,7 +1795,7 @@ TEST_F(VideoSendStreamTest, ChangingTransportOverhead) { class ChangingTransportOverheadTest : public test::EndToEndTest { public: explicit ChangingTransportOverheadTest(TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), task_queue_(task_queue), call_(nullptr), packets_sent_(0), @@ -1851,7 +1871,7 @@ class MaxPaddingSetTest : public test::SendTest { MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun, TaskQueueBase* task_queue) - : SendTest(test::CallTest::kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), running_without_padding_(test_switch_content_type), stream_resetter_(stream_reset_fun), task_queue_(task_queue) { @@ -2009,7 +2029,7 @@ TEST_F(VideoSendStreamTest, } } EXPECT_TRUE( - init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeout)); + init_encode_called_.Wait(test::VideoTestConstants::kDefaultTimeout)); { MutexLock lock(&mutex_); EXPECT_EQ(width, last_initialized_frame_width_); @@ -2049,19 +2069,23 @@ TEST_F(VideoSendStreamTest, CreateSendConfig(1, 0, 0, &transport); GetVideoSendConfig()->encoder_settings.encoder_factory = &encoder_factory; CreateVideoStreams(); - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); frame_generator_capturer_->Start(); }); - encoder.WaitForResolution(kDefaultWidth, kDefaultHeight); + encoder.WaitForResolution(test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); SendTask(task_queue(), [this]() { - frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2, - kDefaultHeight * 2); + frame_generator_capturer_->ChangeResolution( + test::VideoTestConstants::kDefaultWidth * 2, + test::VideoTestConstants::kDefaultHeight * 2); }); - encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2); + encoder.WaitForResolution(test::VideoTestConstants::kDefaultWidth * 2, + test::VideoTestConstants::kDefaultHeight * 2); SendTask(task_queue(), [this]() { DestroyStreams(); @@ -2095,7 +2119,8 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) { } bool WaitForStartBitrate() { - return start_bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeout); + return start_bitrate_changed_.Wait( + test::VideoTestConstants::kDefaultTimeout); } private: @@ -2122,8 +2147,9 @@ TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) { CreateVideoStreams(); // Start capturing and encoding frames to force encoder reconfiguration. - CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth, - kDefaultHeight); + CreateFrameGeneratorCapturer(test::VideoTestConstants::kDefaultFramerate, + test::VideoTestConstants::kDefaultWidth, + test::VideoTestConstants::kDefaultHeight); frame_generator_capturer_->Start(); // TODO(crbug/1255737): Added manual current thread message processing because // the test code context is interpreted as the worker thread and we assume @@ -2173,7 +2199,7 @@ class StartStopBitrateObserver : public test::FakeEncoder { } bool WaitForEncoderInit() { - return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeout); + return encoder_init_.Wait(test::VideoTestConstants::kDefaultTimeout); } bool WaitBitrateChanged(WaitUntil until) { @@ -2190,7 +2216,7 @@ class StartStopBitrateObserver : public test::FakeEncoder { (until == WaitUntil::kZero && *bitrate_kbps == 0)) { return true; } - } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeout)); + } while (bitrate_changed_.Wait(test::VideoTestConstants::kDefaultTimeout)); return false; } @@ -2205,7 +2231,7 @@ TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) { class EncoderStateObserver : public test::SendTest, public VideoEncoder { public: explicit EncoderStateObserver(TaskQueueBase* task_queue) - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), task_queue_(task_queue), stream_(nullptr), initialized_(false), @@ -2338,7 +2364,7 @@ class VideoCodecConfigObserver : public test::SendTest, public: VideoCodecConfigObserver(VideoCodecType video_codec_type, TaskQueueBase* task_queue) - : SendTest(VideoSendStreamTest::kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), video_codec_type_(video_codec_type), stream_(nullptr), @@ -2384,7 +2410,8 @@ class VideoCodecConfigObserver : public test::SendTest, GetEncoderSpecificSettings() const; void PerformTest() override { - EXPECT_TRUE(init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeout)); + EXPECT_TRUE( + init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout)); ASSERT_EQ(1, FakeEncoder::GetNumInitializations()) << "VideoEncoder not initialized."; @@ -2394,7 +2421,8 @@ class VideoCodecConfigObserver : public test::SendTest, SendTask(task_queue_, [&]() { stream_->ReconfigureVideoEncoder(std::move(encoder_config_)); }); - ASSERT_TRUE(init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeout)); + ASSERT_TRUE( + init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout)); EXPECT_EQ(2, FakeEncoder::GetNumInitializations()) << "ReconfigureVideoEncoder did not reinitialize the encoder with " "new encoder settings."; @@ -2539,7 +2567,7 @@ TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) { class RtcpSenderReportTest : public test::SendTest { public: RtcpSenderReportTest() - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), rtp_packets_sent_(0), media_bytes_sent_(0) {} @@ -2614,7 +2642,7 @@ TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) { public test::FakeEncoder { public: ScreencastTargetBitrateTest() - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), test::FakeEncoder(Clock::GetRealTimeClock()), encoder_factory_(this) {} @@ -2672,7 +2700,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { public test::FakeEncoder { public: explicit EncoderBitrateThresholdObserver(TaskQueueBase* task_queue) - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), task_queue_(task_queue), target_bitrate_(0), @@ -2760,7 +2788,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { } } while (bitrate_changed_event_.Wait( std::max(TimeDelta::Millis(1), - VideoSendStreamTest::kDefaultTimeout - + test::VideoTestConstants::kDefaultTimeout - TimeDelta::Millis(rtc::TimeMillis() - start_time)))); MutexLock lock(&mutex_); EXPECT_NEAR(target_bitrate_, expected_bitrate, abs_error) @@ -2801,9 +2829,10 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { void PerformTest() override { ASSERT_TRUE(create_rate_allocator_event_.Wait( - VideoSendStreamTest::kDefaultTimeout)) + test::VideoTestConstants::kDefaultTimeout)) << "Timed out while waiting for rate allocator to be created."; - ASSERT_TRUE(init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeout)) + ASSERT_TRUE( + init_encode_event_.Wait(test::VideoTestConstants::kDefaultTimeout)) << "Timed out while waiting for encoder to be configured."; WaitForSetRates(kStartBitrateKbps, 80); BitrateConstraints bitrate_config; @@ -2820,7 +2849,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy()); }); ASSERT_TRUE(create_rate_allocator_event_.Wait( - VideoSendStreamTest::kDefaultTimeout)); + test::VideoTestConstants::kDefaultTimeout)); EXPECT_EQ(2, num_rate_allocator_creations_) << "Rate allocator should have been recreated."; @@ -2832,7 +2861,7 @@ TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy()); }); ASSERT_TRUE(create_rate_allocator_event_.Wait( - VideoSendStreamTest::kDefaultTimeout)); + test::VideoTestConstants::kDefaultTimeout)); EXPECT_EQ(3, num_rate_allocator_creations_) << "Rate allocator should have been recreated."; @@ -2872,7 +2901,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) { public test::FakeEncoder { public: explicit ScreencastTargetBitrateTest(TaskQueueBase* task_queue) - : SendTest(kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), test::FakeEncoder(Clock::GetRealTimeClock()), send_stream_(nullptr), encoder_factory_(this), @@ -2928,12 +2957,14 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) { SendTask(task_queue_, [&]() { stats = send_stream_->GetStats(); }); for (size_t i = 0; i < kNumStreams; ++i) { - ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) != + ASSERT_TRUE(stats.substreams.find( + test::VideoTestConstants::kVideoSendSsrcs[i]) != stats.substreams.end()) - << "No stats for SSRC: " << kVideoSendSsrcs[i] + << "No stats for SSRC: " + << test::VideoTestConstants::kVideoSendSsrcs[i] << ", stats should exist as soon as frames have been encoded."; VideoSendStream::StreamStats ssrc_stats = - stats.substreams[kVideoSendSsrcs[i]]; + stats.substreams[test::VideoTestConstants::kVideoSendSsrcs[i]]; EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width); EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height); } @@ -2957,7 +2988,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) { class Vp9HeaderObserver : public test::SendTest { public: explicit Vp9HeaderObserver(const Vp9TestParams& params) - : SendTest(VideoSendStreamTest::kLongTimeout), + : SendTest(test::VideoTestConstants::kLongTimeout), encoder_factory_([]() { return VP9Encoder::Create(); }), params_(params), vp9_settings_(VideoEncoder::GetDefaultVp9Settings()) {} @@ -2970,7 +3001,7 @@ class Vp9HeaderObserver : public test::SendTest { virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0; private: - const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType; + const int kVp9PayloadType = test::VideoTestConstants::kVideoSendPayloadType; void ModifyVideoConfigs( VideoSendStream::Config* send_config, @@ -3642,7 +3673,7 @@ TEST_F(VideoSendStreamTest, EncoderConfigMaxFramerateReportedToSource) { class FpsObserver : public test::SendTest, public test::FrameGeneratorCapturer::SinkWantsObserver { public: - FpsObserver() : SendTest(kDefaultTimeout) {} + FpsObserver() : SendTest(test::VideoTestConstants::kDefaultTimeout) {} void OnFrameGeneratorCapturerCreated( test::FrameGeneratorCapturer* frame_generator_capturer) override { @@ -3678,7 +3709,7 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) { public test::FakeEncoder { public: explicit RemoveOverheadFromBandwidthTest(TaskQueueBase* task_queue) - : EndToEndTest(test::CallTest::kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), FakeEncoder(Clock::GetRealTimeClock()), task_queue_(task_queue), encoder_factory_(this), @@ -3733,8 +3764,8 @@ TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) { // At a bitrate of 60kbps with a packet size of 1200B video and an // overhead of 40B per packet video produces 2240bps overhead. // So the encoder BW should be set to 57760bps. - EXPECT_TRUE( - bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeout)); + EXPECT_TRUE(bitrate_changed_event_.Wait( + test::VideoTestConstants::kDefaultTimeout)); { MutexLock lock(&mutex_); EXPECT_LE(max_bitrate_bps_, 57760u); @@ -3757,7 +3788,7 @@ class PacingFactorObserver : public test::SendTest { public: PacingFactorObserver(bool configure_send_side, absl::optional expected_pacing_factor) - : test::SendTest(VideoSendStreamTest::kDefaultTimeout), + : test::SendTest(test::VideoTestConstants::kDefaultTimeout), configure_send_side_(configure_send_side), expected_pacing_factor_(expected_pacing_factor) {} @@ -3854,7 +3885,7 @@ class ContentSwitchTest : public test::SendTest { static const uint32_t kMinPacketsToSend = 50; explicit ContentSwitchTest(T* stream_reset_fun, TaskQueueBase* task_queue) - : SendTest(test::CallTest::kDefaultTimeout), + : SendTest(test::VideoTestConstants::kDefaultTimeout), call_(nullptr), state_(StreamState::kBeforeSwitch), send_stream_(nullptr), @@ -3950,7 +3981,8 @@ class ContentSwitchTest : public test::SendTest { void PerformTest() override { while (GetStreamState() != StreamState::kAfterSwitchBack) { - ASSERT_TRUE(content_switch_event_.Wait(test::CallTest::kDefaultTimeout)); + ASSERT_TRUE(content_switch_event_.Wait( + test::VideoTestConstants::kDefaultTimeout)); (*stream_resetter_)(send_stream_config_, encoder_config_, this); } @@ -4014,7 +4046,7 @@ void VideoSendStreamTest::TestTemporalLayers( const std::string& payload_name, const std::vector& num_temporal_layers, const std::vector& scalability_mode) - : EndToEndTest(kDefaultTimeout), + : EndToEndTest(test::VideoTestConstants::kDefaultTimeout), encoder_factory_(encoder_factory), payload_name_(payload_name), num_temporal_layers_(num_temporal_layers), @@ -4051,7 +4083,8 @@ void VideoSendStreamTest::TestTemporalLayers( webrtc::VideoEncoder::EncoderInfo encoder_info; send_config->encoder_settings.encoder_factory = encoder_factory_; send_config->rtp.payload_name = payload_name_; - send_config->rtp.payload_type = test::CallTest::kVideoSendPayloadType; + send_config->rtp.payload_type = + test::VideoTestConstants::kVideoSendPayloadType; encoder_config->video_format.name = payload_name_; encoder_config->codec_type = PayloadStringToCodecType(payload_name_); encoder_config->video_stream_factory = diff --git a/third_party/libwebrtc/webrtc.gni b/third_party/libwebrtc/webrtc.gni index b1db8ff88415e..15cde6ca33afa 100644 --- a/third_party/libwebrtc/webrtc.gni +++ b/third_party/libwebrtc/webrtc.gni @@ -221,12 +221,6 @@ declare_args() { # WebRTC.framework) rtc_include_builtin_audio_codecs = true - # When set to false, builtin video encoder/decoder factories and all the - # video codecs they depends on will not be included in libwebrtc.{a|lib} - # (they will still be included in libjingle_peerconnection_so.so and - # WebRTC.framework) - rtc_include_builtin_video_codecs = !build_with_mozilla # See Bug 1820869. - # When set to true and in a standalone build, it will undefine UNICODE and # _UNICODE (which are always defined globally by the Chromium Windows # toolchain). diff --git a/third_party/libwebrtc/webrtc_lib_link_test.cc b/third_party/libwebrtc/webrtc_lib_link_test.cc index 055bd969ff7db..868c17287e4aa 100644 --- a/third_party/libwebrtc/webrtc_lib_link_test.cc +++ b/third_party/libwebrtc/webrtc_lib_link_test.cc @@ -18,8 +18,16 @@ #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/stats/rtcstats_objects.h" #include "api/task_queue/default_task_queue_factory.h" -#include "api/video_codecs/builtin_video_decoder_factory.h" -#include "api/video_codecs/builtin_video_encoder_factory.h" +#include "api/video_codecs/video_decoder_factory_template.h" +#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h" +#include "api/video_codecs/video_encoder_factory_template.h" +#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h" +#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "media/engine/webrtc_media_engine.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -36,8 +44,14 @@ cricket::MediaEngineDependencies CreateSomeMediaDeps( webrtc::CreateAudioEncoderFactory(); media_deps.audio_decoder_factory = webrtc::CreateAudioDecoderFactory(); - media_deps.video_encoder_factory = CreateBuiltinVideoEncoderFactory(); - media_deps.video_decoder_factory = webrtc::CreateBuiltinVideoDecoderFactory(); + media_deps.video_encoder_factory = + std::make_unique>(); + media_deps.video_decoder_factory = + std::make_unique>(); media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); return media_deps; } diff --git a/third_party/libwebrtc/whitespace.txt b/third_party/libwebrtc/whitespace.txt index 42d622a4cb0eb..5a84a2562ce70 100644 --- a/third_party/libwebrtc/whitespace.txt +++ b/third_party/libwebrtc/whitespace.txt @@ -2,5 +2,5 @@ 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 an elephant in Stockholm. -Everyone knew about it, but nobody dared say anything. -In the end it didn't make a difference since everyone was working from home. +Why did the elephant get kicked out of the Swedish Parliament? +Because it kept making trunk calls!