WebKit Bugzilla
Attachment 357688 Details for
Bug 192858
: Resync libwebrtc with M72 branch
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-192858-20181219094951.patch (text/plain), 95.37 KB, created by
youenn fablet
on 2018-12-19 09:49:54 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2018-12-19 09:49:54 PST
Size:
95.37 KB
patch
obsolete
>Subversion Revision: 239282 >diff --git a/Source/ThirdParty/libwebrtc/ChangeLog b/Source/ThirdParty/libwebrtc/ChangeLog >index 6e710860cc2b77f91f1f91553de8941abfa0d474..63826e18ea2814afe9f8049ee2297e82cacf5d06 100644 >--- a/Source/ThirdParty/libwebrtc/ChangeLog >+++ b/Source/ThirdParty/libwebrtc/ChangeLog >@@ -1,3 +1,56 @@ >+2018-12-19 Youenn Fablet <youenn@apple.com> >+ >+ Resync libwebrtc with M72 branch >+ https://bugs.webkit.org/show_bug.cgi?id=192858 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Merge changes made upstream. >+ Some of these changes improve support of unified plan and backward compatiblity. >+ >+ * Source/webrtc/api/candidate.cc: >+ * Source/webrtc/api/candidate.h: >+ * Source/webrtc/api/rtpreceiverinterface.h: >+ * Source/webrtc/api/umametrics.h: >+ * Source/webrtc/media/engine/webrtcvideoengine.cc: >+ * Source/webrtc/media/engine/webrtcvideoengine_unittest.cc: >+ * Source/webrtc/modules/audio_processing/agc2/agc2_common.h: >+ * Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc: >+ * Source/webrtc/modules/video_coding/BUILD.gn: >+ * Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc: >+ * Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc: >+ * Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h: >+ * Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc: >+ * Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc: >+ * Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc: >+ * Source/webrtc/modules/video_coding/video_codec_initializer.cc: >+ * Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc: >+ * Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc: >+ * Source/webrtc/p2p/base/port.cc: >+ * Source/webrtc/p2p/base/port.h: >+ * Source/webrtc/p2p/base/portallocator.cc: >+ * Source/webrtc/p2p/client/basicportallocator.cc: >+ * Source/webrtc/p2p/client/basicportallocator_unittest.cc: >+ * Source/webrtc/pc/peerconnection.cc: >+ * Source/webrtc/pc/peerconnection.h: >+ * Source/webrtc/pc/peerconnection_integrationtest.cc: >+ * Source/webrtc/pc/peerconnectioninternal.h: >+ * Source/webrtc/pc/statscollector.cc: >+ * Source/webrtc/pc/statscollector.h: >+ * Source/webrtc/pc/test/fakepeerconnectionbase.h: >+ * Source/webrtc/pc/test/fakepeerconnectionforstats.h: >+ * Source/webrtc/pc/test/mockpeerconnectionobservers.h: >+ (webrtc::MockStatsObserver::OnComplete): >+ (webrtc::MockStatsObserver::TrackIds const): >+ * Source/webrtc/pc/webrtcsdp_unittest.cc: >+ * Source/webrtc/rtc_base/fake_mdns_responder.h: >+ (webrtc::FakeMdnsResponder::GetMappedAddressForName const): >+ * Source/webrtc/rtc_base/fakenetwork.h: >+ (rtc::FakeNetworkManager::CreateMdnsResponder): >+ (rtc::FakeNetworkManager::GetMdnsResponderForTesting const): >+ * Source/webrtc/video/video_send_stream_impl.cc: >+ * Source/webrtc/video/video_stream_encoder.cc: >+ > 2018-12-15 Youenn Fablet <youenn@apple.com> > > Make RTCRtpSender.setParameters to activate specific encodings >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc >index 275b17366c21cdcd0e7d4e5ea3c7808ee5473ca2..5637566f6a9897becd0f2c536e252b81cf332fd6 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc >@@ -125,4 +125,19 @@ bool Candidate::operator!=(const Candidate& o) const { > return !(*this == o); > } > >+Candidate Candidate::ToSanitizedCopy(bool use_hostname_address, >+ bool filter_related_address) const { >+ Candidate copy(*this); >+ if (use_hostname_address) { >+ rtc::SocketAddress hostname_only_addr(address().hostname(), >+ address().port()); >+ copy.set_address(hostname_only_addr); >+ } >+ if (filter_related_address) { >+ copy.set_related_address( >+ rtc::EmptySocketAddressWithFamily(copy.address().family())); >+ } >+ return copy; >+} >+ > } // namespace cricket >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h b/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h >index 4c650d9bdbd52d3c34de0f35406d17b802cfac08..02b4bca82bd306a0bfd1d7f8f1b8698c59cd301a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h >@@ -166,6 +166,16 @@ class RTC_EXPORT Candidate { > bool operator==(const Candidate& o) const; > bool operator!=(const Candidate& o) const; > >+ // Returns a sanitized copy configured by the given booleans. If >+ // |use_host_address| is true, the returned copy has its IP removed from >+ // |address()|, which leads |address()| to be a hostname address. If >+ // |filter_related_address|, the returned copy has its related address reset >+ // to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that >+ // setting both booleans to false returns an identical copy to the original >+ // candidate. >+ Candidate ToSanitizedCopy(bool use_hostname_address, >+ bool filter_related_address) const; >+ > private: > std::string ToStringInternal(bool sensitive) const; > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h b/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h >index 266f6ac7dd672209c2f94d93fd520892c7d6e3bb..2619735ebec26c1ae35653e68c24583ee07e6720 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h >@@ -146,6 +146,7 @@ class RtpReceiverInterface : public rtc::RefCountInterface { > BEGIN_SIGNALING_PROXY_MAP(RtpReceiver) > PROXY_SIGNALING_THREAD_DESTRUCTOR() > PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, track) >+PROXY_CONSTMETHOD0(std::vector<std::string>, stream_ids) > PROXY_CONSTMETHOD0(std::vector<rtc::scoped_refptr<MediaStreamInterface>>, > streams) > PROXY_CONSTMETHOD0(cricket::MediaType, media_type) >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h b/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h >index 88ab08c1bef9a68a437d18f29a9e35adda5d4bb4..239eff3869bb4fc52c615dbab44e87225591c923 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h >@@ -79,12 +79,17 @@ enum IceCandidatePairType { > kIceCandidatePairPrflxSrflx, > kIceCandidatePairPrflxRelay, > >- // The following 4 types tell whether local and remote hosts have private or >- // public IP addresses. >+ // The following 9 types tell whether local and remote hosts have hostname, >+ // private or public IP addresses. > kIceCandidatePairHostPrivateHostPrivate, > kIceCandidatePairHostPrivateHostPublic, > kIceCandidatePairHostPublicHostPrivate, > kIceCandidatePairHostPublicHostPublic, >+ kIceCandidatePairHostNameHostName, >+ kIceCandidatePairHostNameHostPrivate, >+ kIceCandidatePairHostNameHostPublic, >+ kIceCandidatePairHostPrivateHostName, >+ kIceCandidatePairHostPublicHostName, > kIceCandidatePairMax > }; > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc >index 5656e8e7f125b00cfb1cad39d658e0fdaa40ae44..90754482128844a4af0c582e78d918c4d1f0b5a0 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc >@@ -1986,7 +1986,9 @@ WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoderConfig( > RTC_DCHECK_GE(rtp_parameters_.encodings.size(), > encoder_config.number_of_streams); > RTC_DCHECK_GT(encoder_config.number_of_streams, 0); >- encoder_config.simulcast_layers.resize(encoder_config.number_of_streams); >+ >+ // Copy all provided constraints. >+ encoder_config.simulcast_layers.resize(rtp_parameters_.encodings.size()); > for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) { > encoder_config.simulcast_layers[i].active = > rtp_parameters_.encodings[i].active; >@@ -2698,7 +2700,7 @@ std::vector<webrtc::VideoStream> EncoderStreamFactory::CreateEncoderStreams( > RTC_DCHECK_EQ(1, encoder_config.number_of_streams); > } > RTC_DCHECK_GT(encoder_config.number_of_streams, 0); >- RTC_DCHECK_EQ(encoder_config.simulcast_layers.size(), >+ RTC_DCHECK_GE(encoder_config.simulcast_layers.size(), > encoder_config.number_of_streams); > std::vector<webrtc::VideoStream> layers; > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc >index ab04fa6af3e5a6651154905b40887029a9165e9d..4351f559a243044c719f109184d710539d297691 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc >@@ -3120,6 +3120,38 @@ TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) { > EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr)); > } > >+TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) { >+ cricket::VideoSendParameters send_parameters; >+ send_parameters.codecs.push_back(GetEngineCodec("VP9")); >+ ASSERT_TRUE(channel_->SetSendParameters(send_parameters)); >+ >+ const size_t kNumSpatialLayers = 3; >+ std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3); >+ >+ FakeVideoSendStream* stream = >+ AddSendStream(CreateSimStreamParams("cname", ssrcs)); >+ >+ webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]); >+ ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size()); >+ ASSERT_TRUE(parameters.encodings[0].active); >+ ASSERT_TRUE(parameters.encodings[1].active); >+ ASSERT_TRUE(parameters.encodings[2].active); >+ // Invert value to verify copying. >+ parameters.encodings[1].active = false; >+ EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok()); >+ >+ webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy(); >+ >+ // number_of_streams should be 1 since all spatial layers are sent on the >+ // same SSRC. But encoding parameters of all layers is supposed to be copied >+ // and stored in simulcast_layers[]. >+ EXPECT_EQ(1u, encoder_config.number_of_streams); >+ EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers); >+ EXPECT_TRUE(encoder_config.simulcast_layers[0].active); >+ EXPECT_FALSE(encoder_config.simulcast_layers[1].active); >+ EXPECT_TRUE(encoder_config.simulcast_layers[2].active); >+} >+ > class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest { > public: > explicit Vp9SettingsTestWithFieldTrial(const char* field_trials) >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h >index 55dd648db49ab161a1f9850ed4a87e689c61e3d2..a6389f4c2da6a170d970b5993677d48a7696ab21 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h >@@ -41,10 +41,10 @@ constexpr float kMaxNoiseLevelDbfs = -50.f; > // This is the threshold for speech. Speech frames are used for updating the > // speech level, measuring the amount of speech, and decide when to allow target > // gain reduction. >-constexpr float kVadConfidenceThreshold = 0.4f; >+constexpr float kVadConfidenceThreshold = 0.9f; > > // The amount of 'memory' of the Level Estimator. Decides leak factors. >-constexpr size_t kFullBufferSizeMs = 1600; >+constexpr size_t kFullBufferSizeMs = 1200; > constexpr float kFullBufferLeakFactor = 1.f - 1.f / kFullBufferSizeMs; > > constexpr float kInitialSpeechLevelEstimateDbfs = -30.f; >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc >index 67a6919b4660ecc1a6ce17cb87f94b06e4f74d72..30f095117c32ad0dabe2dd548d5e9a25a6838391 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc >@@ -171,11 +171,19 @@ void DesktopAndCursorComposer::OnCaptureResult( > if (frame && cursor_) { > if (frame->rect().Contains(cursor_position_) && > !desktop_capturer_->IsOccluded(cursor_position_)) { >- const float scale = frame->scale_factor(); > DesktopVector relative_position = > cursor_position_.subtract(frame->top_left()); >+#if defined(WEBRTC_MAC) >+ // On OSX, the logical(DIP) and physical coordinates are used mixingly. >+ // For example, the captured cursor has its size in physical pixels(2x) >+ // and location in logical(DIP) pixels on Retina monitor. This will cause >+ // problem when the desktop is mixed with Retina and non-Retina monitors. >+ // So we use DIP pixel for all location info and compensate with the scale >+ // factor of current frame to the |relative_position|. >+ const float scale = frame->scale_factor(); > relative_position.set(relative_position.x() * scale, > relative_position.y() * scale); >+#endif > frame = absl::make_unique<DesktopFrameWithCursor>( > std::move(frame), *cursor_, relative_position); > } >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn >index ac359bc64f827712ef25406d7d2cb06f5a9da475..27955101ebbc937263a1f23eef27b80dfcf41c07 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn >@@ -494,6 +494,7 @@ rtc_static_library("webrtc_vp9_helpers") { > "../../api/video:video_bitrate_allocator", > "../../api/video_codecs:video_codecs_api", > "../../common_video", >+ "../../modules/video_coding:codec_globals_headers", > "../../rtc_base:checks", > ] > } >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc >index 3e922801483928cc13ea31c7dea13a54bdeef3b1..1754195d5c4748adec871e70afa3e824ea0ce38c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc >@@ -14,8 +14,8 @@ > #include <cmath> > #include <vector> > >-#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" >-#include "modules/video_coding/include/video_codec_interface.h" >+#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" >+#include "rtc_base/checks.h" > > namespace webrtc { > >@@ -46,6 +46,7 @@ std::vector<SpatialLayer> ConfigureSvcScreenSharing(size_t input_width, > spatial_layer.maxBitrate = > static_cast<int>(kMaxScreenSharingLayerBitrateKbps[sl_idx]); > spatial_layer.targetBitrate = spatial_layer.maxBitrate; >+ spatial_layer.active = true; > spatial_layers.push_back(spatial_layer); > } > >@@ -69,13 +70,13 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width, > num_spatial_layers = > std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert}); > >- float top_fraction = 0.; > for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { > SpatialLayer spatial_layer = {0}; > spatial_layer.width = input_width >> (num_spatial_layers - sl_idx - 1); > spatial_layer.height = input_height >> (num_spatial_layers - sl_idx - 1); > spatial_layer.maxFramerate = max_framerate_fps; > spatial_layer.numberOfTemporalLayers = num_temporal_layers; >+ spatial_layer.active = true; > > // minBitrate and maxBitrate formulas were derived from > // subjective-quality data to determing bit rates below which video >@@ -95,14 +96,8 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width, > spatial_layer.targetBitrate = > (spatial_layer.minBitrate + spatial_layer.maxBitrate) / 2; > spatial_layers.push_back(spatial_layer); >- top_fraction += std::pow(kSpatialLayeringRateScalingFactor, sl_idx); > } >- // Compute spatial_layers[num_spatial_layers - 1].targetBitrate, which is >- // used to set max_padding_bitrate_. Set max_padding_bitrate_ equal to the >- // minimum total bit rate required to support all spatial layers. >- spatial_layers[num_spatial_layers - 1].targetBitrate = >- static_cast<unsigned int>( >- spatial_layers[num_spatial_layers - 1].minBitrate * top_fraction); >+ > return spatial_layers; > } > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc >index 9b846ade47d7d8186fe46da4ad4152e4f17d909f..4a16e5f814487b9001a6b27089812b0518a2c1d5 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc >@@ -21,8 +21,85 @@ namespace webrtc { > const float kSpatialLayeringRateScalingFactor = 0.55f; > const float kTemporalLayeringRateScalingFactor = 0.55f; > >+static size_t GetNumActiveSpatialLayers(const VideoCodec& codec) { >+ RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9); >+ RTC_DCHECK_GT(codec.VP9().numberOfSpatialLayers, 0u); >+ >+ size_t num_spatial_layers = 0; >+ for (; num_spatial_layers < codec.VP9().numberOfSpatialLayers; >+ ++num_spatial_layers) { >+ if (!codec.spatialLayers[num_spatial_layers].active) { >+ // TODO(bugs.webrtc.org/9350): Deactivation of middle layer is not >+ // implemented. For now deactivation of a VP9 layer deactivates all >+ // layers above the deactivated one. >+ break; >+ } >+ } >+ >+ return num_spatial_layers; >+} >+ >+static bool AdjustAndVerify(const VideoCodec& codec, >+ std::vector<size_t>* spatial_layer_bitrate_bps) { >+ bool enough_bitrate = true; >+ size_t excess_rate = 0; >+ for (size_t sl_idx = 0; >+ sl_idx < spatial_layer_bitrate_bps->size() && enough_bitrate; ++sl_idx) { >+ RTC_DCHECK_GT(codec.spatialLayers[sl_idx].maxBitrate, 0); >+ RTC_DCHECK_GE(codec.spatialLayers[sl_idx].maxBitrate, >+ codec.spatialLayers[sl_idx].minBitrate); >+ >+ const size_t min_bitrate_bps = >+ codec.spatialLayers[sl_idx].minBitrate * 1000; >+ const size_t max_bitrate_bps = >+ codec.spatialLayers[sl_idx].maxBitrate * 1000; >+ >+ spatial_layer_bitrate_bps->at(sl_idx) += excess_rate; >+ if (spatial_layer_bitrate_bps->at(sl_idx) < max_bitrate_bps) { >+ excess_rate = 0; >+ } else { >+ excess_rate = spatial_layer_bitrate_bps->at(sl_idx) - max_bitrate_bps; >+ spatial_layer_bitrate_bps->at(sl_idx) = max_bitrate_bps; >+ } >+ >+ size_t bitrate_bps = spatial_layer_bitrate_bps->at(sl_idx); >+ enough_bitrate = (bitrate_bps >= min_bitrate_bps); >+ } >+ >+ return enough_bitrate; >+} >+ >+static std::vector<size_t> SplitBitrate(size_t num_layers, >+ size_t total_bitrate, >+ float rate_scaling_factor) { >+ std::vector<size_t> bitrates; >+ >+ double denominator = 0.0; >+ for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { >+ denominator += std::pow(rate_scaling_factor, layer_idx); >+ } >+ >+ double numerator = std::pow(rate_scaling_factor, num_layers - 1); >+ for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { >+ bitrates.push_back(numerator * total_bitrate / denominator); >+ numerator /= rate_scaling_factor; >+ } >+ >+ const size_t sum = std::accumulate(bitrates.begin(), bitrates.end(), 0); >+ // Ensure the sum of split bitrates doesn't exceed the total bitrate. >+ RTC_DCHECK_LE(sum, total_bitrate); >+ >+ // Keep the sum of split bitrates equal to the total bitrate by adding bits, >+ // which were lost due to rounding, to the latest layer. >+ bitrates.back() += total_bitrate - sum; >+ >+ return bitrates; >+} >+ > SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec) : codec_(codec) { > RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9); >+ RTC_DCHECK_GT(codec.VP9().numberOfSpatialLayers, 0u); >+ RTC_DCHECK_GT(codec.VP9().numberOfTemporalLayers, 0u); > } > > VideoBitrateAllocation SvcRateAllocator::GetAllocation( >@@ -34,24 +111,27 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocation( > > if (codec_.spatialLayers[0].targetBitrate == 0) { > // Delegate rate distribution to VP9 encoder wrapper if bitrate thresholds >- // are not initialized. >+ // are not set. > VideoBitrateAllocation bitrate_allocation; > bitrate_allocation.SetBitrate(0, 0, total_bitrate_bps); > return bitrate_allocation; >- } else if (codec_.mode == VideoCodecMode::kRealtimeVideo) { >- return GetAllocationNormalVideo(total_bitrate_bps); >+ } >+ >+ size_t num_spatial_layers = GetNumActiveSpatialLayers(codec_); >+ if (num_spatial_layers == 0) { >+ return VideoBitrateAllocation(); // All layers are deactivated. >+ } >+ >+ if (codec_.mode == VideoCodecMode::kRealtimeVideo) { >+ return GetAllocationNormalVideo(total_bitrate_bps, num_spatial_layers); > } else { >- return GetAllocationScreenSharing(total_bitrate_bps); >+ return GetAllocationScreenSharing(total_bitrate_bps, num_spatial_layers); > } > } > > VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo( >- uint32_t total_bitrate_bps) const { >- size_t num_spatial_layers = codec_.VP9().numberOfSpatialLayers; >- RTC_CHECK(num_spatial_layers > 0); >- size_t num_temporal_layers = codec_.VP9().numberOfTemporalLayers; >- RTC_CHECK(num_temporal_layers > 0); >- >+ uint32_t total_bitrate_bps, >+ size_t num_spatial_layers) const { > std::vector<size_t> spatial_layer_bitrate_bps; > > // Distribute total bitrate across spatial layers. If there is not enough >@@ -63,7 +143,8 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo( > SplitBitrate(num_spatial_layers, total_bitrate_bps, > kSpatialLayeringRateScalingFactor); > >- const bool enough_bitrate = AdjustAndVerify(&spatial_layer_bitrate_bps); >+ const bool enough_bitrate = >+ AdjustAndVerify(codec_, &spatial_layer_bitrate_bps); > if (enough_bitrate || num_spatial_layers == 1) { > break; > } >@@ -71,6 +152,7 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo( > > VideoBitrateAllocation bitrate_allocation; > >+ const size_t num_temporal_layers = codec_.VP9().numberOfTemporalLayers; > for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { > std::vector<size_t> temporal_layer_bitrate_bps = > SplitBitrate(num_temporal_layers, spatial_layer_bitrate_bps[sl_idx], >@@ -100,41 +182,9 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationNormalVideo( > return bitrate_allocation; > } > >-bool SvcRateAllocator::AdjustAndVerify( >- std::vector<size_t>* spatial_layer_bitrate_bps) const { >- bool enough_bitrate = true; >- size_t excess_rate = 0; >- for (size_t sl_idx = 0; >- sl_idx < spatial_layer_bitrate_bps->size() && enough_bitrate; ++sl_idx) { >- RTC_DCHECK_GT(codec_.spatialLayers[sl_idx].maxBitrate, 0); >- RTC_DCHECK_GE(codec_.spatialLayers[sl_idx].maxBitrate, >- codec_.spatialLayers[sl_idx].minBitrate); >- >- const size_t min_bitrate_bps = >- codec_.spatialLayers[sl_idx].minBitrate * 1000; >- const size_t max_bitrate_bps = >- codec_.spatialLayers[sl_idx].maxBitrate * 1000; >- >- spatial_layer_bitrate_bps->at(sl_idx) += excess_rate; >- if (spatial_layer_bitrate_bps->at(sl_idx) < max_bitrate_bps) { >- excess_rate = 0; >- } else { >- excess_rate = spatial_layer_bitrate_bps->at(sl_idx) - max_bitrate_bps; >- spatial_layer_bitrate_bps->at(sl_idx) = max_bitrate_bps; >- } >- >- enough_bitrate = (spatial_layer_bitrate_bps->at(sl_idx) >= min_bitrate_bps); >- } >- >- return enough_bitrate; >-} >- > VideoBitrateAllocation SvcRateAllocator::GetAllocationScreenSharing( >- uint32_t total_bitrate_bps) const { >- const size_t num_spatial_layers = codec_.VP9().numberOfSpatialLayers; >- RTC_CHECK(num_spatial_layers > 0); >- RTC_CHECK_EQ(codec_.VP9().numberOfTemporalLayers, 1U); >- >+ uint32_t total_bitrate_bps, >+ size_t num_spatial_layers) const { > VideoBitrateAllocation bitrate_allocation; > > // Add next layer after bitrate of previous layer has reached its maximum. >@@ -158,32 +208,43 @@ VideoBitrateAllocation SvcRateAllocator::GetAllocationScreenSharing( > return bitrate_allocation; > } > >-std::vector<size_t> SvcRateAllocator::SplitBitrate( >- size_t num_layers, >- size_t total_bitrate, >- float rate_scaling_factor) const { >- std::vector<size_t> bitrates; >+uint32_t SvcRateAllocator::GetMaxBitrateBps(const VideoCodec& codec) { >+ const size_t num_spatial_layers = GetNumActiveSpatialLayers(codec); > >- double denominator = 0.0; >- for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { >- denominator += std::pow(rate_scaling_factor, layer_idx); >+ uint32_t max_bitrate_kbps = 0; >+ for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { >+ max_bitrate_kbps += codec.spatialLayers[sl_idx].maxBitrate; > } > >- double numerator = std::pow(rate_scaling_factor, num_layers - 1); >- for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { >- bitrates.push_back(numerator * total_bitrate / denominator); >- numerator /= rate_scaling_factor; >+ if (codec.maxBitrate != 0) { >+ max_bitrate_kbps = std::min(max_bitrate_kbps, codec.maxBitrate); > } > >- const size_t sum = std::accumulate(bitrates.begin(), bitrates.end(), 0); >- // Ensure the sum of split bitrates doesn't exceed the total bitrate. >- RTC_DCHECK_LE(sum, total_bitrate); >+ return max_bitrate_kbps * 1000; >+} > >- // Keep the sum of split bitrates equal to the total bitrate by adding bits, >- // which were lost due to rounding, to the latest layer. >- bitrates.back() += total_bitrate - sum; >+uint32_t SvcRateAllocator::GetPaddingBitrateBps(const VideoCodec& codec) { >+ const size_t num_spatial_layers = GetNumActiveSpatialLayers(codec); > >- return bitrates; >+ if (codec.mode == VideoCodecMode::kRealtimeVideo) { >+ float scale_factor = 0.0; >+ for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { >+ scale_factor += std::pow(kSpatialLayeringRateScalingFactor, sl_idx); >+ } >+ uint32_t min_bitrate_bps = >+ codec.spatialLayers[num_spatial_layers - 1].minBitrate * 1000; >+ return static_cast<uint32_t>(min_bitrate_bps * scale_factor); >+ } >+ >+ RTC_DCHECK(codec.mode == VideoCodecMode::kScreensharing); >+ >+ uint32_t min_bitrate_kbps = 0; >+ for (size_t sl_idx = 0; sl_idx < num_spatial_layers - 1; ++sl_idx) { >+ min_bitrate_kbps += codec.spatialLayers[sl_idx].maxBitrate; >+ } >+ min_bitrate_kbps += codec.spatialLayers[num_spatial_layers - 1].minBitrate; >+ >+ return min_bitrate_kbps * 1000; > } > > } // namespace webrtc >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h >index 10e22edc60307faefaf70b7f324816590fb15314..de5b524c3f116e2a1b4f38f0fc6add7588f79883 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h >@@ -20,9 +20,6 @@ > > namespace webrtc { > >-extern const float kSpatialLayeringRateScalingFactor; >-extern const float kTemporalLayeringRateScalingFactor; >- > class SvcRateAllocator : public VideoBitrateAllocator { > public: > explicit SvcRateAllocator(const VideoCodec& codec); >@@ -30,15 +27,17 @@ class SvcRateAllocator : public VideoBitrateAllocator { > VideoBitrateAllocation GetAllocation(uint32_t total_bitrate_bps, > uint32_t framerate_fps) override; > >+ static uint32_t GetMaxBitrateBps(const VideoCodec& codec); >+ static uint32_t GetPaddingBitrateBps(const VideoCodec& codec); >+ > private: > VideoBitrateAllocation GetAllocationNormalVideo( >- uint32_t total_bitrate_bps) const; >+ uint32_t total_bitrate_bps, >+ size_t num_spatial_layers) const; >+ > VideoBitrateAllocation GetAllocationScreenSharing( >- uint32_t total_bitrate_bps) const; >- std::vector<size_t> SplitBitrate(size_t num_layers, >- size_t total_bitrate, >- float rate_scaling_factor) const; >- bool AdjustAndVerify(std::vector<size_t>* spatial_layer_bitrate_bps) const; >+ uint32_t total_bitrate_bps, >+ size_t num_spatial_layers) const; > > const VideoCodec codec_; > }; >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc >index eec2b9d4199ea9f77e3c99b6cb2d47849bd9f57c..0f132c24a5d96161032942302397a68ca1d1f444 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc >@@ -162,4 +162,89 @@ TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) { > EXPECT_EQ(allocation.GetSpatialLayerSum(1) / 1000, layers[1].minBitrate); > } > >+TEST(SvcRateAllocatorTest, DeativateLayers) { >+ for (int deactivated_idx = 2; deactivated_idx >= 0; --deactivated_idx) { >+ VideoCodec codec = Configure(1280, 720, 3, 1, false); >+ EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U); >+ >+ codec.spatialLayers[deactivated_idx].active = false; >+ >+ SvcRateAllocator allocator = SvcRateAllocator(codec); >+ >+ VideoBitrateAllocation allocation = >+ allocator.GetAllocation(10 * 1000 * 1000, 30); >+ >+ // Ensure layers spatial_idx < deactivated_idx are activated. >+ for (int spatial_idx = 0; spatial_idx < deactivated_idx; ++spatial_idx) { >+ EXPECT_GT(allocation.GetSpatialLayerSum(spatial_idx), 0UL); >+ } >+ >+ // Ensure layers spatial_idx >= deactivated_idx are deactivated. >+ for (int spatial_idx = deactivated_idx; spatial_idx < 3; ++spatial_idx) { >+ EXPECT_EQ(allocation.GetSpatialLayerSum(spatial_idx), 0UL); >+ } >+ } >+} >+ >+class SvcRateAllocatorTestParametrizedContentType >+ : public testing::Test, >+ public testing::WithParamInterface<bool> { >+ public: >+ SvcRateAllocatorTestParametrizedContentType() >+ : is_screen_sharing_(GetParam()) {} >+ >+ const bool is_screen_sharing_; >+}; >+ >+TEST_P(SvcRateAllocatorTestParametrizedContentType, MaxBitrate) { >+ VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_); >+ EXPECT_EQ( >+ SvcRateAllocator::GetMaxBitrateBps(codec), >+ (codec.spatialLayers[0].maxBitrate + codec.spatialLayers[1].maxBitrate + >+ codec.spatialLayers[2].maxBitrate) * >+ 1000); >+ >+ // Deactivate middle layer. This causes deactivation of top layer as well. >+ codec.spatialLayers[1].active = false; >+ EXPECT_EQ(SvcRateAllocator::GetMaxBitrateBps(codec), >+ codec.spatialLayers[0].maxBitrate * 1000); >+} >+ >+TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) { >+ VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_); >+ SvcRateAllocator allocator = SvcRateAllocator(codec); >+ >+ uint32_t padding_bitrate_bps = SvcRateAllocator::GetPaddingBitrateBps(codec); >+ >+ VideoBitrateAllocation allocation = >+ allocator.GetAllocation(padding_bitrate_bps, 30); >+ EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL); >+ EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL); >+ EXPECT_GT(allocation.GetSpatialLayerSum(2), 0UL); >+ >+ // Allocate 90% of padding bitrate. Top layer should be disabled. >+ allocation = allocator.GetAllocation(9 * padding_bitrate_bps / 10, 30); >+ EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL); >+ EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL); >+ EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL); >+ >+ // Deactivate top layer. >+ codec.spatialLayers[2].active = false; >+ >+ padding_bitrate_bps = SvcRateAllocator::GetPaddingBitrateBps(codec); >+ allocation = allocator.GetAllocation(padding_bitrate_bps, 30); >+ EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL); >+ EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL); >+ EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL); >+ >+ allocation = allocator.GetAllocation(9 * padding_bitrate_bps / 10, 30); >+ EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL); >+ EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL); >+ EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL); >+} >+ >+INSTANTIATE_TEST_CASE_P(_, >+ SvcRateAllocatorTestParametrizedContentType, >+ ::testing::Bool()); >+ > } // namespace webrtc >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc >index 4644a31cbb7f64f3db70eaad701d44b2c8005f10..1a9a4dd55f848ace80ad9079c497ec51da42d70f 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc >@@ -331,12 +331,15 @@ TEST_F(TestVp9Impl, EncoderExplicitLayering) { > (codec_settings_.spatialLayers[0].minBitrate + > codec_settings_.spatialLayers[0].maxBitrate) / > 2; >+ codec_settings_.spatialLayers[0].active = true; >+ > codec_settings_.spatialLayers[1].minBitrate = 400; > codec_settings_.spatialLayers[1].maxBitrate = 1500; > codec_settings_.spatialLayers[1].targetBitrate = > (codec_settings_.spatialLayers[1].minBitrate + > codec_settings_.spatialLayers[1].maxBitrate) / > 2; >+ codec_settings_.spatialLayers[1].active = true; > > codec_settings_.spatialLayers[0].width = codec_settings_.width / 2; > codec_settings_.spatialLayers[0].height = codec_settings_.height / 2; >@@ -1029,6 +1032,7 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) { > codec_settings_.startBitrate; > codec_settings_.spatialLayers[sl_idx].targetBitrate = > codec_settings_.startBitrate; >+ codec_settings_.spatialLayers[sl_idx].active = true; > > bitrate_allocation.SetBitrate( > sl_idx, 0, codec_settings_.spatialLayers[sl_idx].targetBitrate * 1000); >@@ -1085,6 +1089,7 @@ TEST_F(TestVp9ImplFrameDropping, LayerMaxFramerateIsCappedByCodecMaxFramerate) { > codec_settings_.spatialLayers[0].minBitrate = codec_settings_.startBitrate; > codec_settings_.spatialLayers[0].maxBitrate = codec_settings_.startBitrate; > codec_settings_.spatialLayers[0].targetBitrate = codec_settings_.startBitrate; >+ codec_settings_.spatialLayers[0].active = true; > > bitrate_allocation.SetBitrate( > 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000); >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc >index 22a08881208a129eb52e35a60d69f96b432f32bd..59cc66707e4c9067cd6decdb09ac43b6ee2b63ea 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc >@@ -14,30 +14,15 @@ > #include "api/video_codecs/sdp_video_format.h" > #include "modules/video_coding/codecs/vp9/vp9_impl.h" > #include "rtc_base/checks.h" >-#include "vpx/vp8cx.h" >-#include "vpx/vp8dx.h" >-#include "vpx/vpx_codec.h" > > namespace webrtc { > > std::vector<SdpVideoFormat> SupportedVP9Codecs() { > #ifdef RTC_ENABLE_VP9 >- // Profile 2 might not be available on some platforms until >- // https://bugs.chromium.org/p/webm/issues/detail?id=1544 is solved. >- static bool vpx_supports_high_bit_depth = >- (vpx_codec_get_caps(vpx_codec_vp9_cx()) & VPX_CODEC_CAP_HIGHBITDEPTH) != >- 0 && >- (vpx_codec_get_caps(vpx_codec_vp9_dx()) & VPX_CODEC_CAP_HIGHBITDEPTH) != >- 0; >- >+ // TODO(emircan): Add Profile 2 support after fixing browser_tests. > std::vector<SdpVideoFormat> supported_formats{SdpVideoFormat( > cricket::kVp9CodecName, > {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}})}; >- if (vpx_supports_high_bit_depth) { >- supported_formats.push_back(SdpVideoFormat( >- cricket::kVp9CodecName, >- {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile2)}})); >- } > return supported_formats; > #else > return std::vector<SdpVideoFormat>(); >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc >index 86a5ab2a4820994fd7402874e9f34f2bbe2ef381..12eac238acdf78d59f4199a32b0b73f9894fff15 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc >@@ -187,6 +187,14 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( > spatial_layers.back().minBitrate = video_codec.minBitrate; > spatial_layers.back().maxBitrate = video_codec.maxBitrate; > } >+ >+ for (size_t spatial_idx = 0; >+ spatial_idx < config.simulcast_layers.size() && >+ spatial_idx < spatial_layers.size(); >+ ++spatial_idx) { >+ spatial_layers[spatial_layers.size() - spatial_idx - 1].active = >+ config.simulcast_layers[spatial_idx].active; >+ } > } > > RTC_DCHECK(!spatial_layers.empty()); >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc >index ceff1ebaf7427bf928fe7e6adbe03c530a187ce3..54fae1b08e3224e1bb1477721a907e81e2eb611b 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc >@@ -286,4 +286,53 @@ TEST_F(VideoCodecInitializerTest, > kDefaultMaxBitrateBps / 1000); > } > >+TEST_F(VideoCodecInitializerTest, >+ Vp9KeepBitrateLimitsIfNumberOfSpatialLayersIsReducedToOne) { >+ // Request 3 spatial layers for 320x180 input. Actual number of layers will be >+ // reduced to 1 due to low input resolution but SVC bitrate limits should be >+ // applied. >+ SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 3, false); >+ VideoStream stream = DefaultStream(); >+ stream.width = 320; >+ stream.height = 180; >+ stream.num_temporal_layers = 3; >+ streams_.push_back(stream); >+ >+ EXPECT_TRUE(InitializeCodec()); >+ EXPECT_LT(codec_out_.spatialLayers[0].maxBitrate, >+ kDefaultMaxBitrateBps / 1000); >+} >+ >+TEST_F(VideoCodecInitializerTest, Vp9DeactivateLayers) { >+ SetUpFor(VideoCodecType::kVideoCodecVP9, 3, 1, false); >+ VideoStream stream = DefaultStream(); >+ streams_.push_back(stream); >+ >+ config_.simulcast_layers.resize(3); >+ >+ // Activate all layers. >+ config_.simulcast_layers[0].active = true; >+ config_.simulcast_layers[1].active = true; >+ config_.simulcast_layers[2].active = true; >+ EXPECT_TRUE(InitializeCodec()); >+ EXPECT_TRUE(codec_out_.spatialLayers[0].active); >+ EXPECT_TRUE(codec_out_.spatialLayers[1].active); >+ EXPECT_TRUE(codec_out_.spatialLayers[2].active); >+ >+ // Deactivate top layer. >+ config_.simulcast_layers[0].active = false; >+ EXPECT_TRUE(InitializeCodec()); >+ EXPECT_TRUE(codec_out_.spatialLayers[0].active); >+ EXPECT_TRUE(codec_out_.spatialLayers[1].active); >+ EXPECT_FALSE(codec_out_.spatialLayers[2].active); >+ >+ // Deactivate middle layer. >+ config_.simulcast_layers[0].active = true; >+ config_.simulcast_layers[1].active = false; >+ EXPECT_TRUE(InitializeCodec()); >+ EXPECT_TRUE(codec_out_.spatialLayers[0].active); >+ EXPECT_FALSE(codec_out_.spatialLayers[1].active); >+ EXPECT_TRUE(codec_out_.spatialLayers[2].active); >+} >+ > } // namespace webrtc >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc >index 8549794b47a874d02a3ad39487da37abb87a99c1..bd767cd2fce4bfb83422821b765e262de638a1bd 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc >@@ -4611,7 +4611,7 @@ TEST_F(P2PTransportChannelTest, > ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts); > // ICE parameter will be set up when creating the channels. > set_remote_ice_parameter_source(FROM_SETICEPARAMETERS); >- GetEndpoint(0)->network_manager_.CreateMdnsResponder(); >+ GetEndpoint(0)->network_manager_.CreateMdnsResponder(rtc::Thread::Current()); > GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory; > CreateChannels(); > // Pause sending candidates from both endpoints until we find out what port >@@ -4682,7 +4682,7 @@ TEST_F(P2PTransportChannelTest, > ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts); > // ICE parameter will be set up when creating the channels. > set_remote_ice_parameter_source(FROM_SETICEPARAMETERS); >- GetEndpoint(0)->network_manager_.CreateMdnsResponder(); >+ GetEndpoint(0)->network_manager_.CreateMdnsResponder(rtc::Thread::Current()); > GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory; > CreateChannels(); > // Pause sending candidates from both endpoints until we find out what port >@@ -4749,7 +4749,7 @@ TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) { > ConfigureEndpoints(OPEN, OPEN, kOnlyLocalPorts, kOnlyLocalPorts); > // ICE parameter will be set up when creating the channels. > set_remote_ice_parameter_source(FROM_SETICEPARAMETERS); >- GetEndpoint(0)->network_manager_.CreateMdnsResponder(); >+ GetEndpoint(0)->network_manager_.CreateMdnsResponder(rtc::Thread::Current()); > GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory; > CreateChannels(); > // Pause sending candidates from both endpoints until we find out what port >@@ -4758,17 +4758,17 @@ TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) { > PauseCandidates(1); > ASSERT_EQ_WAIT(1u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout); > ASSERT_EQ(1u, GetEndpoint(0)->saved_candidates_[0]->candidates.size()); >- const auto& local_candidate = >+ const auto& local_candidate_ep1 = > GetEndpoint(0)->saved_candidates_[0]->candidates[0]; > // The IP address of ep1's host candidate should be obfuscated. >- EXPECT_TRUE(local_candidate.address().IsUnresolvedIP()); >+ EXPECT_TRUE(local_candidate_ep1.address().IsUnresolvedIP()); > // This is the underlying private IP address of the same candidate at ep1, >- // and let the mock resolver of ep2 receives the correct resolution. >- const auto local_address = rtc::SocketAddress( >- kPublicAddrs[0].ipaddr(), local_candidate.address().port()); >+ // and let the mock resolver of ep2 receive the correct resolution. >+ rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address()); >+ resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr()); > > EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _)) >- .WillOnce(DoAll(SetArgPointee<1>(local_address), Return(true))); >+ .WillOnce(DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true))); > // Let ep1 signal its hostname candidate to ep2. > ResumeCandidates(0); > >@@ -4784,4 +4784,103 @@ TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) { > DestroyChannels(); > } > >+// Test that when the IP of a host candidate is concealed by an mDNS name, the >+// stats from the gathering ICE endpoint do not reveal the address of this local >+// host candidate or the related address of a local srflx candidate from the >+// same endpoint. Also, the remote ICE endpoint that successfully resolves a >+// signaled host candidate with an mDNS name should not reveal the address of >+// this remote host candidate in stats. >+TEST_F(P2PTransportChannelTest, >+ CandidatesSanitizedInStatsWhenMdnsObfuscationEnabled) { >+ NiceMock<rtc::MockAsyncResolver> mock_async_resolver; >+ webrtc::MockAsyncResolverFactory mock_async_resolver_factory; >+ EXPECT_CALL(mock_async_resolver_factory, Create()) >+ .WillOnce(Return(&mock_async_resolver)); >+ >+ // ep1 and ep2 will gather host candidates with addresses >+ // kPublicAddrs[0] and kPublicAddrs[1], respectively. ep1 also gathers a srflx >+ // and a relay candidates. >+ ConfigureEndpoints(OPEN, OPEN, >+ kDefaultPortAllocatorFlags | PORTALLOCATOR_DISABLE_TCP, >+ kOnlyLocalPorts); >+ // ICE parameter will be set up when creating the channels. >+ set_remote_ice_parameter_source(FROM_SETICEPARAMETERS); >+ GetEndpoint(0)->network_manager_.CreateMdnsResponder(rtc::Thread::Current()); >+ GetEndpoint(1)->async_resolver_factory_ = &mock_async_resolver_factory; >+ CreateChannels(); >+ // Pause sending candidates from both endpoints until we find out what port >+ // number is assigned to ep1's host candidate. >+ PauseCandidates(0); >+ PauseCandidates(1); >+ // Ep1 has a UDP host, a srflx and a relay candidates. >+ ASSERT_EQ_WAIT(3u, GetEndpoint(0)->saved_candidates_.size(), kMediumTimeout); >+ ASSERT_EQ_WAIT(1u, GetEndpoint(1)->saved_candidates_.size(), kMediumTimeout); >+ >+ for (const auto& candidates_data : GetEndpoint(0)->saved_candidates_) { >+ ASSERT_EQ(1u, candidates_data->candidates.size()); >+ const auto& local_candidate_ep1 = candidates_data->candidates[0]; >+ if (local_candidate_ep1.type() == LOCAL_PORT_TYPE) { >+ // This is the underlying private IP address of the same candidate at ep1, >+ // and let the mock resolver of ep2 receive the correct resolution. >+ rtc::SocketAddress resolved_address_ep1(local_candidate_ep1.address()); >+ resolved_address_ep1.SetResolvedIP(kPublicAddrs[0].ipaddr()); >+ EXPECT_CALL(mock_async_resolver, GetResolvedAddress(_, _)) >+ .WillOnce( >+ DoAll(SetArgPointee<1>(resolved_address_ep1), Return(true))); >+ break; >+ } >+ } >+ ResumeCandidates(0); >+ ResumeCandidates(1); >+ >+ ASSERT_EQ_WAIT(kIceGatheringComplete, ep1_ch1()->gathering_state(), >+ kMediumTimeout); >+ // We should have the following candidate pairs on both endpoints: >+ // ep1_host <-> ep2_host, ep1_srflx <-> ep2_host, ep1_relay <-> ep2_host >+ ASSERT_EQ_WAIT(3u, ep1_ch1()->connections().size(), kMediumTimeout); >+ ASSERT_EQ_WAIT(3u, ep2_ch1()->connections().size(), kMediumTimeout); >+ >+ ConnectionInfos connection_infos_ep1; >+ CandidateStatsList candidate_stats_list_ep1; >+ ConnectionInfos connection_infos_ep2; >+ CandidateStatsList candidate_stats_list_ep2; >+ ep1_ch1()->GetStats(&connection_infos_ep1, &candidate_stats_list_ep1); >+ ep2_ch1()->GetStats(&connection_infos_ep2, &candidate_stats_list_ep2); >+ EXPECT_EQ(3u, connection_infos_ep1.size()); >+ EXPECT_EQ(3u, candidate_stats_list_ep1.size()); >+ EXPECT_EQ(3u, connection_infos_ep2.size()); >+ // Check the stats of ep1 seen by ep1. >+ for (const auto& connection_info : connection_infos_ep1) { >+ const auto& local_candidate = connection_info.local_candidate; >+ if (local_candidate.type() == LOCAL_PORT_TYPE) { >+ EXPECT_TRUE(local_candidate.address().IsUnresolvedIP()); >+ } else if (local_candidate.type() == STUN_PORT_TYPE) { >+ EXPECT_TRUE(local_candidate.related_address().IsAnyIP()); >+ } else if (local_candidate.type() == RELAY_PORT_TYPE) { >+ // The related address of the relay candidate should be equal to the >+ // srflx address. Note that NAT is not configured, hence the following >+ // expectation. >+ EXPECT_EQ(kPublicAddrs[0].ipaddr(), >+ local_candidate.related_address().ipaddr()); >+ } else { >+ FAIL(); >+ } >+ } >+ // Check the stats of ep1 seen by ep2. >+ for (const auto& connection_info : connection_infos_ep2) { >+ const auto& remote_candidate = connection_info.remote_candidate; >+ if (remote_candidate.type() == LOCAL_PORT_TYPE) { >+ EXPECT_TRUE(remote_candidate.address().IsUnresolvedIP()); >+ } else if (remote_candidate.type() == STUN_PORT_TYPE) { >+ EXPECT_TRUE(remote_candidate.related_address().IsAnyIP()); >+ } else if (remote_candidate.type() == RELAY_PORT_TYPE) { >+ EXPECT_EQ(kPublicAddrs[0].ipaddr(), >+ remote_candidate.related_address().ipaddr()); >+ } else { >+ FAIL(); >+ } >+ } >+ DestroyChannels(); >+} >+ > } // namespace cricket >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc >index 4954744cc8e976521c840f14e8a5d09803554359..bb20a4d5da39ed90e24ddbc41cb3db46c445b6b9 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc >@@ -1809,14 +1809,13 @@ ConnectionInfo Connection::stats() { > stats_.timeout = write_state_ == STATE_WRITE_TIMEOUT; > stats_.new_connection = !reported_; > stats_.rtt = rtt_; >- stats_.local_candidate = local_candidate(); >- stats_.remote_candidate = remote_candidate(); > stats_.key = this; > stats_.state = state_; > stats_.priority = priority(); > stats_.nominated = nominated(); > stats_.total_round_trip_time_ms = total_round_trip_time_ms_; > stats_.current_round_trip_time_ms = current_round_trip_time_ms_; >+ CopyCandidatesToStatsAndSanitizeIfNecessary(); > return stats_; > } > >@@ -1893,6 +1892,36 @@ void Connection::MaybeUpdateLocalCandidate(ConnectionRequest* request, > SignalStateChange(this); > } > >+void Connection::CopyCandidatesToStatsAndSanitizeIfNecessary() { >+ auto get_sanitized_copy = [](const Candidate& c) { >+ bool use_hostname_address = c.type() == LOCAL_PORT_TYPE; >+ bool filter_related_address = c.type() == STUN_PORT_TYPE; >+ return c.ToSanitizedCopy(use_hostname_address, filter_related_address); >+ }; >+ >+ if (port_->Network()->GetMdnsResponder() != nullptr) { >+ // When the mDNS obfuscation of local IPs is enabled, we sanitize local >+ // candidates. >+ stats_.local_candidate = get_sanitized_copy(local_candidate()); >+ } else { >+ stats_.local_candidate = local_candidate(); >+ } >+ >+ if (!remote_candidate().address().hostname().empty()) { >+ // If the remote endpoint signaled us a hostname candidate, we assume it is >+ // supposed to be sanitized in the stats. >+ // >+ // A prflx remote candidate should not have a hostname set. >+ RTC_DCHECK(remote_candidate().type() != PRFLX_PORT_TYPE); >+ // A remote hostname candidate should have a resolved IP before we can form >+ // a candidate pair. >+ RTC_DCHECK(!remote_candidate().address().IsUnresolvedIP()); >+ stats_.remote_candidate = get_sanitized_copy(remote_candidate()); >+ } else { >+ stats_.remote_candidate = remote_candidate(); >+ } >+} >+ > bool Connection::rtt_converged() const { > return rtt_samples_ > (RTT_RATIO + 1); > } >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h >index e0b3f078603777f55bf5fb4d9e9d86038aec307f..17047b7f4b3bf7ae1671e17cdea3f70a875368b4 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h >@@ -784,6 +784,8 @@ class Connection : public CandidatePairInterface, > void MaybeUpdateLocalCandidate(ConnectionRequest* request, > StunMessage* response); > >+ void CopyCandidatesToStatsAndSanitizeIfNecessary(); >+ > void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type); > void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type); > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc >index d3b3a56edd926c7c0a0314bc53c86a472974c22b..063574b25bac5e9e727796d8c5dfac1703c43c5a 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc >@@ -89,6 +89,14 @@ void PortAllocatorSession::GetCandidateStatsFromReadyPorts( > for (const auto& candidate : candidates) { > CandidateStats candidate_stats(candidate); > port->GetStunStats(&candidate_stats.stun_stats); >+ bool mdns_obfuscation_enabled = >+ port->Network()->GetMdnsResponder() != nullptr; >+ if (mdns_obfuscation_enabled) { >+ bool use_hostname_address = candidate.type() == LOCAL_PORT_TYPE; >+ bool filter_related_address = candidate.type() == STUN_PORT_TYPE; >+ candidate_stats.candidate = candidate_stats.candidate.ToSanitizedCopy( >+ use_hostname_address, filter_related_address); >+ } > candidate_stats_list->push_back(std::move(candidate_stats)); > } > } >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc >index 39895dfa5a16d07f2813815aee7b07317857aedf..47f13d0db3b291d1656140ef8d9dd9be41bbaa0e 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc >@@ -521,14 +521,10 @@ void BasicPortAllocatorSession::GetCandidatesFromPort( > Candidate BasicPortAllocatorSession::SanitizeCandidate( > const Candidate& c) const { > RTC_DCHECK_RUN_ON(network_thread_); >- Candidate copy = c; > // If the candidate has a generated hostname, we need to obfuscate its IP > // address when signaling this candidate. >- if (!c.address().hostname().empty() && !c.address().IsUnresolvedIP()) { >- rtc::SocketAddress hostname_only_addr(c.address().hostname(), >- c.address().port()); >- copy.set_address(hostname_only_addr); >- } >+ bool use_hostname_address = >+ !c.address().hostname().empty() && !c.address().IsUnresolvedIP(); > // If adapter enumeration is disabled or host candidates are disabled, > // clear the raddr of STUN candidates to avoid local address leakage. > bool filter_stun_related_address = >@@ -538,12 +534,10 @@ Candidate BasicPortAllocatorSession::SanitizeCandidate( > // If the candidate filter doesn't allow reflexive addresses, empty TURN raddr > // to avoid reflexive address leakage. > bool filter_turn_related_address = !(candidate_filter_ & CF_REFLEXIVE); >- if ((c.type() == STUN_PORT_TYPE && filter_stun_related_address) || >- (c.type() == RELAY_PORT_TYPE && filter_turn_related_address)) { >- copy.set_related_address( >- rtc::EmptySocketAddressWithFamily(copy.address().family())); >- } >- return copy; >+ bool filter_related_address = >+ ((c.type() == STUN_PORT_TYPE && filter_stun_related_address) || >+ (c.type() == RELAY_PORT_TYPE && filter_turn_related_address)); >+ return c.ToSanitizedCopy(use_hostname_address, filter_related_address); > } > > bool BasicPortAllocatorSession::CandidatesAllocationDone() const { >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc >index a07569e94b8dfa5aa56c4256159888a8663ad6f2..7aab073dacfb9ead42b4d528b8c83a0dbdb5f293 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc >@@ -2257,7 +2257,7 @@ TEST_F(BasicPortAllocatorTest, HostCandidateAddressIsReplacedByHostname) { > AddTurnServers(kTurnUdpIntIPv6Addr, kTurnTcpIntIPv6Addr); > > ASSERT_EQ(&network_manager_, allocator().network_manager()); >- network_manager_.CreateMdnsResponder(); >+ network_manager_.CreateMdnsResponder(rtc::Thread::Current()); > AddInterface(kClientAddr); > ASSERT_TRUE(CreateSession(ICE_CANDIDATE_COMPONENT_RTP)); > session_->StartGettingPorts(); >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc >index 3be0671bb48e05618be6e4dd6263a796c8298967..4f0a8ea01127622720d0cbddc2e1e17cc940225c 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc >@@ -277,16 +277,32 @@ IceCandidatePairType GetIceCandidatePairCounter( > const auto& relay = RELAY_PORT_TYPE; > const auto& prflx = PRFLX_PORT_TYPE; > if (l == host && r == host) { >+ bool local_hostname = >+ !local.address().hostname().empty() && local.address().IsUnresolvedIP(); >+ bool remote_hostname = !remote.address().hostname().empty() && >+ remote.address().IsUnresolvedIP(); > bool local_private = IPIsPrivate(local.address().ipaddr()); > bool remote_private = IPIsPrivate(remote.address().ipaddr()); >- if (local_private) { >- if (remote_private) { >+ if (local_hostname) { >+ if (remote_hostname) { >+ return kIceCandidatePairHostNameHostName; >+ } else if (remote_private) { >+ return kIceCandidatePairHostNameHostPrivate; >+ } else { >+ return kIceCandidatePairHostNameHostPublic; >+ } >+ } else if (local_private) { >+ if (remote_hostname) { >+ return kIceCandidatePairHostPrivateHostName; >+ } else if (remote_private) { > return kIceCandidatePairHostPrivateHostPrivate; > } else { > return kIceCandidatePairHostPrivateHostPublic; > } > } else { >- if (remote_private) { >+ if (remote_hostname) { >+ return kIceCandidatePairHostPublicHostName; >+ } else if (remote_private) { > return kIceCandidatePairHostPublicHostPrivate; > } else { > return kIceCandidatePairHostPublicHostPublic; >@@ -518,33 +534,6 @@ bool VerifyIceUfragPwdPresent(const SessionDescription* desc) { > return true; > } > >-bool GetTrackIdBySsrc(const SessionDescription* session_description, >- uint32_t ssrc, >- std::string* track_id) { >- RTC_DCHECK(track_id != NULL); >- >- const cricket::AudioContentDescription* audio_desc = >- cricket::GetFirstAudioContentDescription(session_description); >- if (audio_desc) { >- const auto* found = cricket::GetStreamBySsrc(audio_desc->streams(), ssrc); >- if (found) { >- *track_id = found->id; >- return true; >- } >- } >- >- const cricket::VideoContentDescription* video_desc = >- cricket::GetFirstVideoContentDescription(session_description); >- if (video_desc) { >- const auto* found = cricket::GetStreamBySsrc(video_desc->streams(), ssrc); >- if (found) { >- *track_id = found->id; >- return true; >- } >- } >- return false; >-} >- > // Get the SCTP port out of a SessionDescription. > // Return -1 if not found. > int GetSctpPort(const SessionDescription* session_description) { >@@ -2495,6 +2484,18 @@ RTCError PeerConnection::ApplyRemoteDescription( > } > media_streams.push_back(stream); > } >+ // Special case: "a=msid" missing, use random stream ID. >+ if (media_streams.empty() && >+ !(remote_description()->description()->msid_signaling() & >+ cricket::kMsidSignalingMediaSection)) { >+ if (!missing_msid_default_stream_) { >+ missing_msid_default_stream_ = MediaStreamProxy::Create( >+ rtc::Thread::Current(), >+ MediaStream::Create(rtc::CreateRandomUuid())); >+ added_streams.push_back(missing_msid_default_stream_); >+ } >+ media_streams.push_back(missing_msid_default_stream_); >+ } > // This will add the remote track to the streams. > // TODO(hbos): When we remove remote_streams(), use set_stream_ids() > // instead. https://crbug.com/webrtc/9480 >@@ -5255,22 +5256,34 @@ cricket::IceConfig PeerConnection::ParseIceConfig( > return ice_config; > } > >-bool PeerConnection::GetLocalTrackIdBySsrc(uint32_t ssrc, >- std::string* track_id) { >- if (!local_description()) { >- return false; >+static absl::string_view GetTrackIdBySsrc( >+ const SessionDescriptionInterface* session_description, >+ uint32_t ssrc) { >+ if (!session_description) { >+ return {}; >+ } >+ for (const cricket::ContentInfo& content : >+ session_description->description()->contents()) { >+ const cricket::MediaContentDescription& media = >+ *content.media_description(); >+ if (media.type() == cricket::MEDIA_TYPE_AUDIO || >+ media.type() == cricket::MEDIA_TYPE_VIDEO) { >+ const cricket::StreamParams* stream_params = >+ cricket::GetStreamBySsrc(media.streams(), ssrc); >+ if (stream_params) { >+ return stream_params->id; >+ } >+ } > } >- return webrtc::GetTrackIdBySsrc(local_description()->description(), ssrc, >- track_id); >+ return {}; > } > >-bool PeerConnection::GetRemoteTrackIdBySsrc(uint32_t ssrc, >- std::string* track_id) { >- if (!remote_description()) { >- return false; >- } >- return webrtc::GetTrackIdBySsrc(remote_description()->description(), ssrc, >- track_id); >+absl::string_view PeerConnection::GetLocalTrackIdBySsrc(uint32_t ssrc) { >+ return GetTrackIdBySsrc(local_description(), ssrc); >+} >+ >+absl::string_view PeerConnection::GetRemoteTrackIdBySsrc(uint32_t ssrc) { >+ return GetTrackIdBySsrc(remote_description(), ssrc); > } > > bool PeerConnection::SendData(const cricket::SendDataParams& params, >@@ -6433,7 +6446,8 @@ void PeerConnection::ReportBestConnectionState( > kBestConnections_IPv6, > kPeerConnectionAddressFamilyCounter_Max); > } else { >- RTC_CHECK(0); >+ RTC_CHECK(!local.address().hostname().empty() && >+ local.address().IsUnresolvedIP()); > } > > return; >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h >index 7e97afab7c605395db0c9b404463682e515d376b..1810f1c2bcd26e328b6f85eabc78a38cf0df55c8 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h >@@ -225,8 +225,8 @@ class PeerConnection : public PeerConnectionInternal, > return transceivers_; > } > >- bool GetLocalTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override; >- bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override; >+ absl::string_view GetLocalTrackIdBySsrc(uint32_t ssrc) override; >+ absl::string_view GetRemoteTrackIdBySsrc(uint32_t ssrc) override; > > sigslot::signal1<DataChannel*>& SignalDataChannelCreated() override { > return SignalDataChannelCreated_; >@@ -1030,6 +1030,11 @@ class PeerConnection : public PeerConnectionInternal, > std::vector< > rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>> > transceivers_; >+ // In Unified Plan, if we encounter remote SDP that does not contain an a=msid >+ // line we create and use a stream with a random ID for our receivers. This is >+ // to support legacy endpoints that do not support the a=msid attribute (as >+ // opposed to streamless tracks with "a=msid:-"). >+ rtc::scoped_refptr<MediaStreamInterface> missing_msid_default_stream_; > // MIDs that have been seen either by SetLocalDescription or > // SetRemoteDescription over the life of the PeerConnection. > std::set<std::string> seen_mids_; >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc >index a7f7aad0f54b31caed3ea7fd45f63f47c94a9ee0..a8c2432734768cf158e969bdcc44ea9aa2a9d9c8 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc >@@ -22,6 +22,7 @@ > #include <utility> > #include <vector> > >+#include "absl/memory/memory.h" > #include "api/audio_codecs/builtin_audio_decoder_factory.h" > #include "api/audio_codecs/builtin_audio_encoder_factory.h" > #include "api/mediastreaminterface.h" >@@ -76,12 +77,14 @@ using cricket::FakeWebRtcVideoEncoderFactory; > using cricket::MediaContentDescription; > using cricket::StreamParams; > using rtc::SocketAddress; >+using ::testing::_; > using ::testing::Combine; > using ::testing::ElementsAre; > using ::testing::Return; >+using ::testing::NiceMock; > using ::testing::SetArgPointee; >+using ::testing::UnorderedElementsAreArray; > using ::testing::Values; >-using ::testing::_; > using webrtc::DataBuffer; > using webrtc::DataChannelInterface; > using webrtc::DtmfSender; >@@ -149,6 +152,7 @@ void RemoveSsrcsAndMsids(cricket::SessionDescription* desc) { > content.media_description()->mutable_streams().clear(); > } > desc->set_msid_supported(false); >+ desc->set_msid_signaling(0); > } > > // Removes all stream information besides the stream ids, simulating an >@@ -214,17 +218,6 @@ class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface { > cricket::MediaType expected_media_type_; > }; > >-// Used by PeerConnectionWrapper::OnIceCandidate to allow a test to modify an >-// ICE candidate before it is signaled. >-class IceCandidateReplacerInterface { >- public: >- virtual ~IceCandidateReplacerInterface() = default; >- // Return nullptr to drop the candidate (it won't be signaled to the other >- // side). >- virtual std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate( >- const webrtc::IceCandidateInterface*) = 0; >-}; >- > // Helper class that wraps a peer connection, observes it, and can accept > // signaling messages from another wrapper. > // >@@ -306,9 +299,8 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, > remote_offer_handler_ = std::move(handler); > } > >- void SetLocalIceCandidateReplacer( >- std::unique_ptr<IceCandidateReplacerInterface> replacer) { >- local_ice_candidate_replacer_ = std::move(replacer); >+ void SetRemoteAsyncResolver(rtc::MockAsyncResolver* resolver) { >+ remote_async_resolver_ = resolver; > } > > // Every ICE connection state in order that has been seen by the observer. >@@ -938,46 +930,32 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, > EXPECT_EQ(pc()->ice_gathering_state(), new_state); > ice_gathering_state_history_.push_back(new_state); > } >- std::unique_ptr<webrtc::IceCandidateInterface> ReplaceIceCandidate( >- const webrtc::IceCandidateInterface* candidate) { >- std::string candidate_string; >- candidate->ToString(&candidate_string); >- >- auto owned_candidate = >- local_ice_candidate_replacer_->ReplaceCandidate(candidate); >- if (!owned_candidate) { >- RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer dropped \"" >- << candidate_string << "\""; >- return nullptr; >- } >- std::string owned_candidate_string; >- owned_candidate->ToString(&owned_candidate_string); >- RTC_LOG(LS_INFO) << "LocalIceCandidateReplacer changed \"" >- << candidate_string << "\" to \"" << owned_candidate_string >- << "\""; >- return owned_candidate; >- } > void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override { > RTC_LOG(LS_INFO) << debug_name_ << ": OnIceCandidate"; > >- const webrtc::IceCandidateInterface* new_candidate = candidate; >- std::unique_ptr<webrtc::IceCandidateInterface> owned_candidate; >- if (local_ice_candidate_replacer_) { >- owned_candidate = ReplaceIceCandidate(candidate); >- if (!owned_candidate) { >- return; // The candidate was dropped. >+ if (remote_async_resolver_) { >+ const auto& local_candidate = candidate->candidate(); >+ const auto& mdns_responder = network()->GetMdnsResponderForTesting(); >+ if (local_candidate.address().IsUnresolvedIP()) { >+ RTC_DCHECK(local_candidate.type() == cricket::LOCAL_PORT_TYPE); >+ rtc::SocketAddress resolved_addr(local_candidate.address()); >+ const auto resolved_ip = mdns_responder->GetMappedAddressForName( >+ local_candidate.address().hostname()); >+ RTC_DCHECK(!resolved_ip.IsNil()); >+ resolved_addr.SetResolvedIP(resolved_ip); >+ EXPECT_CALL(*remote_async_resolver_, GetResolvedAddress(_, _)) >+ .WillOnce(DoAll(SetArgPointee<1>(resolved_addr), Return(true))); >+ EXPECT_CALL(*remote_async_resolver_, Destroy(_)); > } >- new_candidate = owned_candidate.get(); > } > > std::string ice_sdp; >- EXPECT_TRUE(new_candidate->ToString(&ice_sdp)); >+ EXPECT_TRUE(candidate->ToString(&ice_sdp)); > if (signaling_message_receiver_ == nullptr || !signal_ice_candidates_) { > // Remote party may be deleted. > return; > } >- SendIceMessage(new_candidate->sdp_mid(), new_candidate->sdp_mline_index(), >- ice_sdp); >+ SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp); > } > void OnDataChannel( > rtc::scoped_refptr<DataChannelInterface> data_channel) override { >@@ -1021,7 +999,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, > std::function<void(cricket::SessionDescription*)> received_sdp_munger_; > std::function<void(cricket::SessionDescription*)> generated_sdp_munger_; > std::function<void()> remote_offer_handler_; >- std::unique_ptr<IceCandidateReplacerInterface> local_ice_candidate_replacer_; >+ rtc::MockAsyncResolver* remote_async_resolver_ = nullptr; > rtc::scoped_refptr<DataChannelInterface> data_channel_; > std::unique_ptr<MockDataChannelObserver> data_observer_; > >@@ -1480,6 +1458,15 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { > return old; > } > >+ void SetPortAllocatorFlags(uint32_t caller_flags, uint32_t callee_flags) { >+ network_thread()->Invoke<void>( >+ RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags, >+ caller()->port_allocator(), caller_flags)); >+ network_thread()->Invoke<void>( >+ RTC_FROM_HERE, rtc::Bind(&cricket::PortAllocator::set_flags, >+ callee()->port_allocator(), callee_flags)); >+ } >+ > rtc::FirewallSocketServer* firewall() const { return fss_.get(); } > > // Expects the provided number of new frames to be received within >@@ -2449,6 +2436,37 @@ TEST_F(PeerConnectionIntegrationTestUnifiedPlan, > EXPECT_TRUE(ExpectNewFrames(media_expectations)); > } > >+TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLinePresent) { >+ ASSERT_TRUE(CreatePeerConnectionWrappers()); >+ ConnectFakeSignaling(); >+ caller()->AddAudioTrack(); >+ caller()->AddVideoTrack(); >+ caller()->CreateAndSetAndSignalOffer(); >+ ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); >+ auto callee_receivers = callee()->pc()->GetReceivers(); >+ ASSERT_EQ(2u, callee_receivers.size()); >+ EXPECT_TRUE(callee_receivers[0]->stream_ids().empty()); >+ EXPECT_TRUE(callee_receivers[1]->stream_ids().empty()); >+} >+ >+TEST_F(PeerConnectionIntegrationTestUnifiedPlan, NoStreamsMsidLineMissing) { >+ ASSERT_TRUE(CreatePeerConnectionWrappers()); >+ ConnectFakeSignaling(); >+ caller()->AddAudioTrack(); >+ caller()->AddVideoTrack(); >+ callee()->SetReceivedSdpMunger(RemoveSsrcsAndMsids); >+ caller()->CreateAndSetAndSignalOffer(); >+ ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); >+ auto callee_receivers = callee()->pc()->GetReceivers(); >+ ASSERT_EQ(2u, callee_receivers.size()); >+ ASSERT_EQ(1u, callee_receivers[0]->stream_ids().size()); >+ ASSERT_EQ(1u, callee_receivers[1]->stream_ids().size()); >+ EXPECT_EQ(callee_receivers[0]->stream_ids()[0], >+ callee_receivers[1]->stream_ids()[0]); >+ EXPECT_EQ(callee_receivers[0]->streams()[0], >+ callee_receivers[1]->streams()[0]); >+} >+ > // Test that if two video tracks are sent (from caller to callee, in this test), > // they're transmitted correctly end-to-end. > TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithTwoVideoTracks) { >@@ -2616,6 +2634,34 @@ TEST_P(PeerConnectionIntegrationTest, GetCaptureStartNtpTimeWithOldStatsApi) { > 2 * kMaxWaitForFramesMs); > } > >+// Test that the track ID is associated with all local and remote SSRC stats >+// using the old GetStats() and more than 1 audio and more than 1 video track. >+// This is a regression test for crbug.com/906988 >+TEST_F(PeerConnectionIntegrationTestUnifiedPlan, >+ OldGetStatsAssociatesTrackIdForManyMediaSections) { >+ ASSERT_TRUE(CreatePeerConnectionWrappers()); >+ ConnectFakeSignaling(); >+ auto audio_sender_1 = caller()->AddAudioTrack(); >+ auto video_sender_1 = caller()->AddVideoTrack(); >+ auto audio_sender_2 = caller()->AddAudioTrack(); >+ auto video_sender_2 = caller()->AddVideoTrack(); >+ caller()->CreateAndSetAndSignalOffer(); >+ ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); >+ >+ MediaExpectations media_expectations; >+ media_expectations.CalleeExpectsSomeAudioAndVideo(); >+ ASSERT_TRUE_WAIT(ExpectNewFrames(media_expectations), kDefaultTimeout); >+ >+ std::vector<std::string> track_ids = { >+ audio_sender_1->track()->id(), video_sender_1->track()->id(), >+ audio_sender_2->track()->id(), video_sender_2->track()->id()}; >+ >+ auto caller_stats = caller()->OldGetStats(); >+ EXPECT_THAT(caller_stats->TrackIds(), UnorderedElementsAreArray(track_ids)); >+ auto callee_stats = callee()->OldGetStats(); >+ EXPECT_THAT(callee_stats->TrackIds(), UnorderedElementsAreArray(track_ids)); >+} >+ > // Test that we can get stats (using the new stats implemnetation) for > // unsignaled streams. Meaning when SSRCs/MSIDs aren't signaled explicitly in > // SDP. >@@ -3552,81 +3598,48 @@ TEST_P(PeerConnectionIntegrationTest, IceStatesReachCompletion) { > callee()->ice_connection_state(), kDefaultTimeout); > } > >-// Replaces the first candidate with a static address and configures a >-// MockAsyncResolver to return the replaced address the first time the static >-// address is resolved. Candidates past the first will not be signaled. >-class ReplaceFirstCandidateAddressDropOthers final >- : public IceCandidateReplacerInterface { >- public: >- ReplaceFirstCandidateAddressDropOthers( >- const SocketAddress& new_address, >- rtc::MockAsyncResolver* mock_async_resolver) >- : mock_async_resolver_(mock_async_resolver), new_address_(new_address) { >- RTC_DCHECK(mock_async_resolver); >- } >+constexpr int kOnlyLocalPorts = cricket::PORTALLOCATOR_DISABLE_STUN | >+ cricket::PORTALLOCATOR_DISABLE_RELAY | >+ cricket::PORTALLOCATOR_DISABLE_TCP; > >- std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate( >- const webrtc::IceCandidateInterface* candidate) override { >- if (replaced_candidate_) { >- return nullptr; >- } >+// Use a mock resolver to resolve the hostname back to the original IP on both >+// sides and check that the ICE connection connects. >+TEST_P(PeerConnectionIntegrationTest, >+ IceStatesReachCompletionWithRemoteHostname) { >+ auto caller_resolver_factory = >+ absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>(); >+ auto callee_resolver_factory = >+ absl::make_unique<NiceMock<webrtc::MockAsyncResolverFactory>>(); >+ NiceMock<rtc::MockAsyncResolver> callee_async_resolver; >+ NiceMock<rtc::MockAsyncResolver> caller_async_resolver; > >- replaced_candidate_ = true; >- cricket::Candidate new_candidate(candidate->candidate()); >- new_candidate.set_address(new_address_); >- EXPECT_CALL(*mock_async_resolver_, GetResolvedAddress(_, _)) >- .WillOnce(DoAll(SetArgPointee<1>(candidate->candidate().address()), >- Return(true))); >- EXPECT_CALL(*mock_async_resolver_, Destroy(_)); >- return webrtc::CreateIceCandidate( >- candidate->sdp_mid(), candidate->sdp_mline_index(), new_candidate); >- } >+ // This also verifies that the injected AsyncResolverFactory is used by >+ // P2PTransportChannel. >+ EXPECT_CALL(*caller_resolver_factory, Create()) >+ .WillOnce(Return(&caller_async_resolver)); >+ webrtc::PeerConnectionDependencies caller_deps(nullptr); >+ caller_deps.async_resolver_factory = std::move(caller_resolver_factory); > >- private: >- rtc::MockAsyncResolver* mock_async_resolver_; >- SocketAddress new_address_; >- bool replaced_candidate_ = false; >-}; >+ EXPECT_CALL(*callee_resolver_factory, Create()) >+ .WillOnce(Return(&callee_async_resolver)); >+ webrtc::PeerConnectionDependencies callee_deps(nullptr); >+ callee_deps.async_resolver_factory = std::move(callee_resolver_factory); > >-// Drops all candidates before they are signaled. >-class DropAllCandidates final : public IceCandidateReplacerInterface { >- public: >- std::unique_ptr<webrtc::IceCandidateInterface> ReplaceCandidate( >- const webrtc::IceCandidateInterface*) override { >- return nullptr; >- } >-}; >+ PeerConnectionInterface::RTCConfiguration config; >+ config.bundle_policy = PeerConnectionInterface::kBundlePolicyMaxBundle; >+ config.rtcp_mux_policy = PeerConnectionInterface::kRtcpMuxPolicyRequire; > >-// Replace the first caller ICE candidate IP with a fake hostname and drop the >-// other candidates. Drop all candidates on the callee side (to avoid a prflx >-// connection). Use a mock resolver to resolve the hostname back to the original >-// IP on the callee side and check that the ice connection connects. >-TEST_P(PeerConnectionIntegrationTest, >- IceStatesReachCompletionWithRemoteHostname) { >- webrtc::MockAsyncResolverFactory* callee_mock_async_resolver_factory; >- { >- auto resolver_factory = >- absl::make_unique<webrtc::MockAsyncResolverFactory>(); >- callee_mock_async_resolver_factory = resolver_factory.get(); >- webrtc::PeerConnectionDependencies callee_deps(nullptr); >- callee_deps.async_resolver_factory = std::move(resolver_factory); >+ ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps( >+ config, std::move(caller_deps), config, std::move(callee_deps))); > >- ASSERT_TRUE(CreatePeerConnectionWrappersWithConfigAndDeps( >- RTCConfiguration(), webrtc::PeerConnectionDependencies(nullptr), >- RTCConfiguration(), std::move(callee_deps))); >- } >+ caller()->SetRemoteAsyncResolver(&callee_async_resolver); >+ callee()->SetRemoteAsyncResolver(&caller_async_resolver); > >- rtc::MockAsyncResolver mock_async_resolver; >+ // Enable hostname candidates with mDNS names. >+ caller()->network()->CreateMdnsResponder(network_thread()); >+ callee()->network()->CreateMdnsResponder(network_thread()); > >- // This also verifies that the injected AsyncResolverFactory is used by >- // P2PTransportChannel. >- EXPECT_CALL(*callee_mock_async_resolver_factory, Create()) >- .WillOnce(Return(&mock_async_resolver)); >- caller()->SetLocalIceCandidateReplacer( >- absl::make_unique<ReplaceFirstCandidateAddressDropOthers>( >- SocketAddress("a.b", 10000), &mock_async_resolver)); >- callee()->SetLocalIceCandidateReplacer( >- absl::make_unique<DropAllCandidates>()); >+ SetPortAllocatorFlags(kOnlyLocalPorts, kOnlyLocalPorts); > > ConnectFakeSignaling(); > caller()->AddAudioVideoTracks(); >@@ -3637,6 +3650,10 @@ TEST_P(PeerConnectionIntegrationTest, > caller()->ice_connection_state(), kDefaultTimeout); > EXPECT_EQ_WAIT(webrtc::PeerConnectionInterface::kIceConnectionConnected, > callee()->ice_connection_state(), kDefaultTimeout); >+ >+ EXPECT_EQ(1, webrtc::metrics::NumEvents( >+ "WebRTC.PeerConnection.CandidatePairType_UDP", >+ webrtc::kIceCandidatePairHostNameHostName)); > } > > // Test that firewalling the ICE connection causes the clients to identify the >@@ -3661,14 +3678,8 @@ class PeerConnectionIntegrationIceStatesTest > } > > void SetPortAllocatorFlags() { >- network_thread()->Invoke<void>( >- RTC_FROM_HERE, >- rtc::Bind(&cricket::PortAllocator::set_flags, >- caller()->port_allocator(), port_allocator_flags_)); >- network_thread()->Invoke<void>( >- RTC_FROM_HERE, >- rtc::Bind(&cricket::PortAllocator::set_flags, >- callee()->port_allocator(), port_allocator_flags_)); >+ PeerConnectionIntegrationBaseTest::SetPortAllocatorFlags( >+ port_allocator_flags_, port_allocator_flags_); > } > > std::vector<SocketAddress> CallerAddresses() { >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h >index 8a169547cc43af75310709c82fbb6c2c3e15c4c4..cb3627bfbc6601655151ec3f236d562c3ee1aaae 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h >@@ -42,8 +42,8 @@ class PeerConnectionInternal : public PeerConnectionInterface { > GetTransceiversInternal() const = 0; > > // Get the id used as a media stream track's "id" field from ssrc. >- virtual bool GetLocalTrackIdBySsrc(uint32_t ssrc, std::string* track_id) = 0; >- virtual bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id) = 0; >+ virtual absl::string_view GetLocalTrackIdBySsrc(uint32_t ssrc) = 0; >+ virtual absl::string_view GetRemoteTrackIdBySsrc(uint32_t ssrc) = 0; > > virtual sigslot::signal1<DataChannel*>& SignalDataChannelCreated() = 0; > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc >index a1d52db04e92de8d457c93a0689a85221acd7140..3cd85e69b23bf36513060debaad39c71434b85f2 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc >@@ -586,28 +586,31 @@ StatsReport* StatsCollector::PrepareReport(bool local, > StatsReport* report = reports_.Find(id); > > // Use the ID of the track that is currently mapped to the SSRC, if any. >- std::string track_id; >- if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) { >+ absl::string_view track_id = GetTrackIdBySsrc(ssrc, direction); >+ if (track_id.empty()) { > // The SSRC is not used by any existing track (or lookup failed since the > // SSRC wasn't signaled in SDP). Try copying the track ID from a previous > // report: if one exists. > if (report) { > const StatsReport::Value* v = > report->FindValue(StatsReport::kStatsValueNameTrackId); >- if (v) >+ if (v) { > track_id = v->string_val(); >+ } > } > } > >- if (!report) >+ if (!report) { > report = reports_.InsertNew(id); >+ } > > // FYI - for remote reports, the timestamp will be overwritten later. > report->set_timestamp(stats_gathering_started_); > > report->AddInt64(StatsReport::kStatsValueNameSsrc, ssrc); > if (!track_id.empty()) { >- report->AddString(StatsReport::kStatsValueNameTrackId, track_id); >+ report->AddString(StatsReport::kStatsValueNameTrackId, >+ std::string(track_id)); > } > // Add the mapping of SSRC to transport. > report->AddId(StatsReport::kStatsValueNameTransportId, transport_id); >@@ -1095,26 +1098,24 @@ void StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track, > } > } > >-bool StatsCollector::GetTrackIdBySsrc(uint32_t ssrc, >- std::string* track_id, >- StatsReport::Direction direction) { >+absl::string_view StatsCollector::GetTrackIdBySsrc( >+ uint32_t ssrc, >+ StatsReport::Direction direction) { > RTC_DCHECK(pc_->signaling_thread()->IsCurrent()); >+ absl::string_view track_id; > if (direction == StatsReport::kSend) { >- if (!pc_->GetLocalTrackIdBySsrc(ssrc, track_id)) { >- RTC_LOG(LS_WARNING) << "The SSRC " << ssrc >- << " is not associated with a sending track"; >- return false; >- } >+ track_id = pc_->GetLocalTrackIdBySsrc(ssrc); > } else { >- RTC_DCHECK(direction == StatsReport::kReceive); >- if (!pc_->GetRemoteTrackIdBySsrc(ssrc, track_id)) { >- RTC_LOG(LS_WARNING) << "The SSRC " << ssrc >- << " is not associated with a receiving track"; >- return false; >- } >+ RTC_DCHECK_EQ(direction, StatsReport::kReceive); >+ track_id = pc_->GetRemoteTrackIdBySsrc(ssrc); > } >- >- return true; >+ if (track_id.empty()) { >+ RTC_LOG(LS_WARNING) << "The SSRC " << ssrc << " is not associated with a " >+ << (direction == StatsReport::kSend ? "sending" >+ : "receiving") >+ << " track"; >+ } >+ return track_id; > } > > void StatsCollector::UpdateTrackReports() { >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h >index a3c5992afc65f829512e76ccbfb879bdd4122c37..25bffcc2dfe98fb529016109b24f942e5e8f9516 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h >@@ -128,9 +128,8 @@ class StatsCollector { > > // Helper method to get the id for the track identified by ssrc. > // |direction| tells if the track is for sending or receiving. >- bool GetTrackIdBySsrc(uint32_t ssrc, >- std::string* track_id, >- StatsReport::Direction direction); >+ absl::string_view GetTrackIdBySsrc(uint32_t ssrc, >+ StatsReport::Direction direction); > > // Helper method to update the timestamp of track records. > void UpdateTrackReports(); >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h >index 93380c0953eb5f7424c1675835b5c894497a3938..c190628beb9725685553af70f664d7cb8af67a8d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h >@@ -229,11 +229,9 @@ class FakePeerConnectionBase : public PeerConnectionInternal { > return {}; > } > >- bool GetLocalTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override { >- return false; >- } >- bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override { >- return false; >+ absl::string_view GetLocalTrackIdBySsrc(uint32_t ssrc) override { return {}; } >+ absl::string_view GetRemoteTrackIdBySsrc(uint32_t ssrc) override { >+ return {}; > } > > sigslot::signal1<DataChannel*>& SignalDataChannelCreated() override { >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h >index af86639eca4d59849f6d5ee89a451e4b6400b217..a9f9d17d16948d57f9516737978d72c75c027ce1 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h >@@ -249,24 +249,20 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase { > return transceivers_; > } > >- bool GetLocalTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override { >+ absl::string_view GetLocalTrackIdBySsrc(uint32_t ssrc) override { > auto it = local_track_id_by_ssrc_.find(ssrc); > if (it != local_track_id_by_ssrc_.end()) { >- *track_id = it->second; >- return true; >- } else { >- return false; >+ return it->second; > } >+ return {}; > } > >- bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override { >+ absl::string_view GetRemoteTrackIdBySsrc(uint32_t ssrc) override { > auto it = remote_track_id_by_ssrc_.find(ssrc); > if (it != remote_track_id_by_ssrc_.end()) { >- *track_id = it->second; >- return true; >- } else { >- return false; >+ return it->second; > } >+ return {}; > } > > std::vector<rtc::scoped_refptr<DataChannel>> sctp_data_channels() >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h >index 62c0c9415f6c4183bece1278870e2b067ad43903..0657853c29f2e98d426a707ddbedfa6649bf1904 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h >@@ -366,6 +366,9 @@ class MockStatsObserver : public webrtc::StatsObserver { > &stats_.bytes_sent); > GetInt64Value(r, StatsReport::kStatsValueNameCaptureStartNtpTimeMs, > &stats_.capture_start_ntp_time); >+ stats_.track_ids.emplace_back(); >+ GetStringValue(r, StatsReport::kStatsValueNameTrackId, >+ &stats_.track_ids.back()); > } else if (r->type() == StatsReport::kStatsReportTypeBwe) { > stats_.timestamp = r->timestamp(); > GetIntValue(r, StatsReport::kStatsValueNameAvailableReceiveBandwidth, >@@ -424,6 +427,11 @@ class MockStatsObserver : public webrtc::StatsObserver { > return stats_.srtp_cipher; > } > >+ std::vector<std::string> TrackIds() const { >+ RTC_CHECK(called_); >+ return stats_.track_ids; >+ } >+ > private: > bool GetIntValue(const StatsReport* report, > StatsReport::StatsValueName name, >@@ -469,6 +477,7 @@ class MockStatsObserver : public webrtc::StatsObserver { > available_receive_bandwidth = 0; > dtls_cipher.clear(); > srtp_cipher.clear(); >+ track_ids.clear(); > } > > size_t number_of_reports; >@@ -481,6 +490,7 @@ class MockStatsObserver : public webrtc::StatsObserver { > int available_receive_bandwidth; > std::string dtls_cipher; > std::string srtp_cipher; >+ std::vector<std::string> track_ids; > } stats_; > }; > >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc >index e7c5c77bb61ade2b5f948926610257b10965d07a..6775957498fd9cf20d8142bfb219a267962e0c92 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc >@@ -2474,6 +2474,8 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutMsid) { > EXPECT_TRUE(SdpDeserialize(sdp_without_msid, &jdesc)); > // Verify > EXPECT_TRUE(CompareSessionDescription(jdesc_, jdesc)); >+ EXPECT_FALSE(jdesc.description()->msid_signaling() & >+ ~cricket::kMsidSignalingSsrcAttribute); > } > > TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithExtmapAllowMixed) { >@@ -3470,6 +3472,9 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionSpecialMsid) { > &deserialized_description)); > > EXPECT_TRUE(CompareSessionDescription(jdesc_, deserialized_description)); >+ EXPECT_EQ(cricket::kMsidSignalingMediaSection | >+ cricket::kMsidSignalingSsrcAttribute, >+ deserialized_description.description()->msid_signaling()); > } > > // Tests the serialization of a Unified Plan SDP that is compatible for both >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h b/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h >index 1e60a5d9de2d1ccc4fdf154bf6b30598d5b65bc5..17a76784fc51476eb70145f3f86d30d3a2d96c0d 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h >@@ -50,6 +50,15 @@ class FakeMdnsResponder : public MdnsResponderInterface { > [callback, result]() { callback(result); }); > } > >+ rtc::IPAddress GetMappedAddressForName(const std::string& name) const { >+ for (const auto& addr_name_pair : addr_name_map_) { >+ if (addr_name_pair.second == name) { >+ return addr_name_pair.first; >+ } >+ } >+ return rtc::IPAddress(); >+ } >+ > private: > uint32_t next_available_id_ = 0; > std::map<rtc::IPAddress, std::string> addr_name_map_; >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h b/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h >index cb890ec583dc876be6f4d44d2ebdf0803c05ab57..9acf9694535bcae99741bc2b806e0964da709253 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h >@@ -82,20 +82,25 @@ class FakeNetworkManager : public NetworkManagerBase, public MessageHandler { > // MessageHandler interface. > virtual void OnMessage(Message* msg) { DoUpdateNetworks(); } > >- void CreateMdnsResponder() { >+ void CreateMdnsResponder(rtc::Thread* network_thread) { > if (mdns_responder_ == nullptr) { > mdns_responder_ = >- absl::make_unique<webrtc::FakeMdnsResponder>(rtc::Thread::Current()); >+ absl::make_unique<webrtc::FakeMdnsResponder>(network_thread); > } > } > > using NetworkManagerBase::set_enumeration_permission; > using NetworkManagerBase::set_default_local_addresses; > >+ // rtc::NetworkManager override. > webrtc::MdnsResponderInterface* GetMdnsResponder() const override { > return mdns_responder_.get(); > } > >+ webrtc::FakeMdnsResponder* GetMdnsResponderForTesting() const { >+ return mdns_responder_.get(); >+ } >+ > private: > void DoUpdateNetworks() { > if (start_count_ == 0) >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc >index 5dcf18243d5f876f01206750464b197fb3c2d149..52e5568a8c05ef9df5e15c9e2b9ddcb0e826b884 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc >@@ -545,7 +545,8 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( > const VideoCodecType codec_type = > PayloadStringToCodecType(config_->rtp.payload_name); > if (codec_type == kVideoCodecVP9) { >- max_padding_bitrate_ = streams[0].target_bitrate_bps; >+ max_padding_bitrate_ = has_alr_probing_ ? streams[0].min_bitrate_bps >+ : streams[0].target_bitrate_bps; > } else { > max_padding_bitrate_ = CalculateMaxPadBitrateBps( > streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate, >diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc b/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc >index a22d58adf1eaadf887bc54b387f0e4d62e6cee4e..c94699bcd7a5124cc2015c0e08299e1065b34079 100644 >--- a/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc >+++ b/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc >@@ -18,6 +18,7 @@ > #include "api/video/encoded_image.h" > #include "api/video/i420_buffer.h" > #include "api/video/video_bitrate_allocator_factory.h" >+#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h" > #include "modules/video_coding/include/video_codec_initializer.h" > #include "modules/video_coding/include/video_coding.h" > #include "rtc_base/arraysize.h" >@@ -545,24 +546,13 @@ void VideoStreamEncoder::ReconfigureEncoder() { > > // Set min_bitrate_bps, max_bitrate_bps, and max padding bit rate for VP9. > if (encoder_config_.codec_type == kVideoCodecVP9) { >- RTC_DCHECK_EQ(1U, streams.size()); >- int max_encoder_bitrate_kbps = 0; >- for (int i = 0; i < codec.VP9()->numberOfSpatialLayers; ++i) { >- max_encoder_bitrate_kbps += codec.spatialLayers[i].maxBitrate; >- } > // Lower max bitrate to the level codec actually can produce. >- streams[0].max_bitrate_bps = >- std::min(streams[0].max_bitrate_bps, max_encoder_bitrate_kbps * 1000); >+ streams[0].max_bitrate_bps = std::min<int>( >+ streams[0].max_bitrate_bps, SvcRateAllocator::GetMaxBitrateBps(codec)); > streams[0].min_bitrate_bps = codec.spatialLayers[0].minBitrate * 1000; >- // Pass along the value of maximum padding bit rate from >- // spatialLayers[].targetBitrate to streams[0].target_bitrate_bps. >- // TODO(ssilkin): There should be some margin between max padding bitrate >- // and max encoder bitrate. With the current logic they can be equal. >+ // target_bitrate_bps specifies the maximum padding bitrate. > streams[0].target_bitrate_bps = >- std::min(static_cast<unsigned int>(streams[0].max_bitrate_bps), >- codec.spatialLayers[codec.VP9()->numberOfSpatialLayers - 1] >- .targetBitrate * >- 1000); >+ SvcRateAllocator::GetPaddingBitrateBps(codec); > } > > codec.startBitrate =
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192858
: 357688