Drop frames in RtpVideoSender::OnEncodedImage if stream disabled
Drops frames if the encoder has been configured with a new set of rtp streams and a stray frame is returned from an encoder. This can happen with hardware encoders that may deliver frames on a separate thread than were they are configured. This cl disable sending media on the RTP module a video layer is connected to and there by, old frames are dropped. Bug: webrtc:1200, b/201798527 Change-Id: Id6bcfc3a846f6b8ed3b645cbbde571b819611a75 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/271122 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37744}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
c06c0cfa52
commit
fb8641c4e6
@ -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<int>(i);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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, {});
|
||||
|
Reference in New Issue
Block a user