diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc index 1f55eb8a0d..a7e2f692ab 100644 --- a/call/rtp_video_sender.cc +++ b/call/rtp_video_sender.cc @@ -511,7 +511,7 @@ void RtpVideoSender::SetActiveModulesLocked( } RtpRtcpInterface& rtp_module = *rtp_streams_[i].rtp_rtcp; - const bool was_active = rtp_module.SendingMedia(); + const bool was_active = rtp_module.Sending(); const bool should_be_active = active_modules[i]; // Sends a kRtcpByeCode when going from true to false. @@ -669,6 +669,14 @@ void RtpVideoSender::OnVideoLayersAllocationUpdated( stream_allocation.rtp_stream_index = i; rtp_streams_[i].sender_video->SetVideoLayersAllocation( std::move(stream_allocation)); + // Only send video frames on the rtp module if the encoder is configured + // to send. This is to prevent stray frames to be sent after an encoder + // has been reconfigured. + rtp_streams_[i].rtp_rtcp->SetSendingMediaStatus( + absl::c_any_of(allocation.active_spatial_layers, + [&i](const VideoLayersAllocation::SpatialLayer layer) { + return layer.rtp_stream_index == static_cast(i); + })); } } } diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc index fef0495ee3..ee3e8458dd 100644 --- a/call/rtp_video_sender_unittest.cc +++ b/call/rtp_video_sender_unittest.cc @@ -330,6 +330,41 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) { test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); } +TEST( + RtpVideoSenderTest, + DiscardsHigherSpatialVideoFramesAfterLayerDisabledInVideoLayersAllocation) { + constexpr uint8_t kPayload = 'a'; + EncodedImage encoded_image_1; + encoded_image_1.SetTimestamp(1); + encoded_image_1.capture_time_ms_ = 2; + encoded_image_1._frameType = VideoFrameType::kVideoFrameKey; + encoded_image_1.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1)); + EncodedImage encoded_image_2(encoded_image_1); + encoded_image_2.SetSpatialIndex(1); + CodecSpecificInfo codec_info; + codec_info.codecType = kVideoCodecVP8; + RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, + kPayloadType, {}); + test.SetActiveModules({true, true}); + // A layer is sent on both rtp streams. + test.router()->OnVideoLayersAllocationUpdated( + {.active_spatial_layers = {{.rtp_stream_index = 0}, + {.rtp_stream_index = 1}}}); + + EXPECT_EQ(EncodedImageCallback::Result::OK, + test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); + EXPECT_EQ(EncodedImageCallback::Result::OK, + test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); + + // Only rtp stream index 0 is configured to send a stream. + test.router()->OnVideoLayersAllocationUpdated( + {.active_spatial_layers = {{.rtp_stream_index = 0}}}); + EXPECT_EQ(EncodedImageCallback::Result::OK, + test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); + EXPECT_NE(EncodedImageCallback::Result::OK, + test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); +} + TEST(RtpVideoSenderTest, CreateWithNoPreviousStates) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {});