Diff
Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/ChangeLog 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog 2018-12-19 22:45:12 UTC (rev 239396)
@@ -1,3 +1,56 @@
+2018-12-19 Youenn Fablet <you...@apple.com>
+
+ Resync libwebrtc with M72 branch
+ https://bugs.webkit.org/show_bug.cgi?id=192858
+
+ Reviewed by Eric Carlson.
+
+ 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 <you...@apple.com>
Make RTCRtpSender.setParameters to activate specific encodings
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -125,4 +125,19 @@
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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/candidate.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -166,6 +166,16 @@
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;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/rtpreceiverinterface.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -146,6 +146,7 @@
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)
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/api/umametrics.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -79,12 +79,17 @@
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
};
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -1986,7 +1986,9 @@
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 @@
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;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/media/engine/webrtcvideoengine_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -3120,6 +3120,38 @@
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)
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/audio_processing/agc2/agc2_common.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -41,10 +41,10 @@
// 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;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -171,11 +171,19 @@
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);
}
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/BUILD.gn 2018-12-19 22:45:12 UTC (rev 239396)
@@ -494,6 +494,7 @@
"../../api/video:video_bitrate_allocator",
"../../api/video_codecs:video_codecs_api",
"../../common_video",
+ "../../modules/video_coding:codec_globals_headers",
"../../rtc_base:checks",
]
}
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_config.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -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 @@
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,7 +70,6 @@
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);
@@ -76,6 +76,7 @@
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 @@
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;
}
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -21,8 +21,85 @@
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 @@
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 @@
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 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 @@
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 @@
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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -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 @@
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_;
};
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/svc_rate_allocator_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -162,4 +162,89 @@
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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -331,6 +331,8 @@
(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 =
@@ -337,6 +339,7 @@
(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 @@
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 @@
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);
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/codecs/vp9/vp9.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -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>();
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -187,6 +187,14 @@
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());
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/modules/video_coding/video_codec_initializer_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -286,4 +286,53 @@
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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/p2ptransportchannel_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -4611,7 +4611,7 @@
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 @@
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 @@
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 @@
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 @@
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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -1809,8 +1809,6 @@
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();
@@ -1817,6 +1815,7 @@
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 @@
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);
}
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/port.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -784,6 +784,8 @@
void MaybeUpdateLocalCandidate(ConnectionRequest* request,
StunMessage* response);
+ void CopyCandidatesToStatsAndSanitizeIfNecessary();
+
void LogCandidatePairConfig(webrtc::IceCandidatePairConfigType type);
void LogCandidatePairEvent(webrtc::IceCandidatePairEventType type);
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/base/portallocator.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -89,6 +89,14 @@
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));
}
}
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -521,14 +521,10 @@
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 @@
// 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 {
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/p2p/client/basicportallocator_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -2257,7 +2257,7 @@
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();
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -277,16 +277,32 @@
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 @@
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 @@
}
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,24 +5256,36 @@
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 {};
}
- return webrtc::GetTrackIdBySsrc(local_description()->description(), ssrc,
- track_id);
+ 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 {};
}
-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,
const rtc::CopyOnWriteBuffer& payload,
cricket::SendDataResult* result) {
@@ -6433,7 +6446,8 @@
kBestConnections_IPv6,
kPeerConnectionAddressFamilyCounter_Max);
} else {
- RTC_CHECK(0);
+ RTC_CHECK(!local.address().hostname().empty() &&
+ local.address().IsUnresolvedIP());
}
return;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -225,8 +225,8 @@
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 @@
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_;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnection_integrationtest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -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::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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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() {
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/peerconnectioninternal.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -42,8 +42,8 @@
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;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -586,8 +586,8 @@
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.
@@ -594,13 +594,15 @@
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_);
@@ -607,7 +609,8 @@
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 @@
}
}
-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() {
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/statscollector.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -128,9 +128,8 @@
// 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();
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionbase.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -229,12 +229,10 @@
return {};
}
- bool GetLocalTrackIdBySsrc(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 {};
}
- bool GetRemoteTrackIdBySsrc(uint32_t ssrc, std::string* track_id) override {
- return false;
- }
sigslot::signal1<DataChannel*>& SignalDataChannelCreated() override {
return SignalDataChannelCreated_;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/fakepeerconnectionforstats.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -249,24 +249,20 @@
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()
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/test/mockpeerconnectionobservers.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -366,6 +366,9 @@
&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 @@
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 @@
available_receive_bandwidth = 0;
dtls_cipher.clear();
srtp_cipher.clear();
+ track_ids.clear();
}
size_t number_of_reports;
@@ -481,6 +490,7 @@
int available_receive_bandwidth;
std::string dtls_cipher;
std::string srtp_cipher;
+ std::vector<std::string> track_ids;
} stats_;
};
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/pc/webrtcsdp_unittest.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -2474,6 +2474,8 @@
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 @@
&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
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fake_mdns_responder.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -50,6 +50,15 @@
[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_;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/rtc_base/fakenetwork.h 2018-12-19 22:45:12 UTC (rev 239396)
@@ -82,10 +82,10 @@
// 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);
}
}
@@ -92,10 +92,15 @@
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)
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_send_stream_impl.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -545,7 +545,8 @@
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,
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc (239395 => 239396)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc 2018-12-19 22:24:04 UTC (rev 239395)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/video/video_stream_encoder.cc 2018-12-19 22:45:12 UTC (rev 239396)
@@ -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 @@
// 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 =