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) {