From 33d2a91737946a5aa43864f0aa4136907b2d41fe Mon Sep 17 00:00:00 2001 From: Ilya Nikolaevskiy Date: Tue, 2 Apr 2019 11:05:03 +0200 Subject: [PATCH] Fix target bitrate RTCP messages behavior for SVC streams MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a better solution than https://webrtc-review.googlesource.com/c/src/+/129929 (which got reverted). This CL instead filters out unused SSRCs from RtpConfig for RtpVideoSender. Bug: webrtc:10485 Change-Id: Iaa8d07681419a2387c8253eb38e08a0828e9e688 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130505 Reviewed-by: Niels Moller Reviewed-by: Erik Språng Commit-Queue: Ilya Nikolaevskiy Cr-Commit-Position: refs/heads/master@{#27433} --- media/engine/webrtc_video_engine.cc | 18 +++++++++-- media/engine/webrtc_video_engine_unittest.cc | 32 +++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index acbc36f701..ca357be7e2 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1996,8 +1996,13 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::UpdateSendState() { RTC_DCHECK_RUN_ON(&thread_checker_); if (sending_) { RTC_DCHECK(stream_ != nullptr); - std::vector active_layers(rtp_parameters_.encodings.size()); - for (size_t i = 0; i < active_layers.size(); ++i) { + size_t num_layers = rtp_parameters_.encodings.size(); + if (parameters_.encoder_config.number_of_streams == 1) { + // SVC is used. Only one simulcast layer is present. + num_layers = 1; + } + std::vector active_layers(num_layers); + for (size_t i = 0; i < num_layers; ++i) { active_layers[i] = rtp_parameters_.encodings[i].active; } // This updates what simulcast layers are sending, and possibly starts @@ -2302,6 +2307,15 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::RecreateWebRtcStream() { "payload type the set codec. Ignoring RTX."; config.rtp.rtx.ssrcs.clear(); } + if (parameters_.encoder_config.number_of_streams == 1) { + // SVC is used instead of simulcast. Remove unnecessary SSRCs. + if (config.rtp.ssrcs.size() > 1) { + config.rtp.ssrcs.resize(1); + if (config.rtp.rtx.ssrcs.size() > 1) { + config.rtp.rtx.ssrcs.resize(1); + } + } + } stream_ = call_->CreateVideoSendStream(std::move(config), parameters_.encoder_config.Copy()); diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index da205e1219..58c97ac3a3 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -3063,7 +3063,6 @@ TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) { AddSendStream(CreateSimStreamParams("cname", ssrcs)); webrtc::VideoSendStream::Config config = stream->GetConfig().Copy(); - EXPECT_EQ(ssrcs.size(), config.rtp.ssrcs.size()); webrtc::test::FrameForwarder frame_forwarder; EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder)); @@ -3082,6 +3081,36 @@ TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) { EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr)); } +TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) { + cricket::VideoSendParameters parameters; + parameters.codecs.push_back(GetEngineCodec("VP9")); + ASSERT_TRUE(channel_->SetSendParameters(parameters)); + + std::vector ssrcs = MAKE_VECTOR(kSsrcs3); + + FakeVideoSendStream* stream = + AddSendStream(CreateSimStreamParams("cname", ssrcs)); + + webrtc::VideoSendStream::Config config = stream->GetConfig().Copy(); + + // Despite 3 ssrcs provided, single layer is used. + EXPECT_EQ(1u, config.rtp.ssrcs.size()); + + webrtc::test::FrameForwarder frame_forwarder; + EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder)); + channel_->SetSend(true); + + frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame()); + + webrtc::VideoCodecVP9 vp9_settings; + ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; + + const size_t kNumSpatialLayers = ssrcs.size(); + EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers); + + EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr)); +} + TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) { cricket::VideoSendParameters send_parameters; send_parameters.codecs.push_back(GetEngineCodec("VP9")); @@ -7090,6 +7119,7 @@ class WebRtcVideoChannelSimulcastTest : public testing::Test { std::vector video_streams = stream->GetVideoStreams(); ASSERT_EQ(expected_num_streams, video_streams.size()); + EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size()); std::vector expected_streams; if (conference_mode) {