Keep the video send stream alive if the encoder drop frames.

The encoder can drop all frames for extended periods if it has produced over budget. After 2 seconds without any encoded frames, the video send stream times out and deallocates the stream.

Ideally the send stream should keep track if frames are captured instead of encoded, but keeping the stream alive using OnDroppedFrame can work as a proxy for that.

Bug: webrtc:11062
Change-Id: Id7ec1ff333427643453c4a36d1db03ca826cd9ea
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/158700
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29662}
This commit is contained in:
Jakob Ivarsson
2019-10-30 14:02:14 +01:00
committed by Commit Bot
parent c35333d1fd
commit 159b417c98
4 changed files with 45 additions and 0 deletions

View File

@ -627,6 +627,11 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
return result;
}
void VideoSendStreamImpl::OnDroppedFrame(
EncodedImageCallback::DropReason reason) {
activity_ = true;
}
std::map<uint32_t, RtpState> VideoSendStreamImpl::GetRtpStates() const {
return rtp_video_sender_->GetRtpStates();
}

View File

@ -128,6 +128,9 @@ class VideoSendStreamImpl : public webrtc::BitrateAllocatorObserver,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override;
// Implements EncodedImageCallback.
void OnDroppedFrame(EncodedImageCallback::DropReason reason) override;
// Implements VideoBitrateAllocationObserver.
void OnBitrateAllocationUpdated(
const VideoBitrateAllocation& allocation) override;

View File

@ -858,5 +858,41 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) {
ASSERT_TRUE(done.Wait(10000));
}
TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) {
std::unique_ptr<VideoSendStreamImpl> vss_impl;
test_queue_.SendTask(
[&] {
vss_impl = CreateVideoSendStreamImpl(
kDefaultInitialBitrateBps, kDefaultBitratePriority,
VideoEncoderConfig::ContentType::kRealtimeVideo);
vss_impl->Start();
const uint32_t kBitrateBps = 100000;
EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps())
.Times(1)
.WillOnce(Return(kBitrateBps));
static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(CreateAllocation(kBitrateBps));
// Keep the stream from deallocating by dropping a frame.
static_cast<EncodedImageCallback*>(vss_impl.get())
->OnDroppedFrame(
EncodedImageCallback::DropReason::kDroppedByEncoder);
EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get()))
.Times(0);
},
RTC_FROM_HERE);
rtc::Event done;
test_queue_.PostDelayedTask(
[&] {
testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_);
vss_impl->Stop();
vss_impl.reset();
done.Set();
},
2000);
ASSERT_TRUE(done.Wait(5000));
}
} // namespace internal
} // namespace webrtc

View File

@ -1776,6 +1776,7 @@ void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
});
break;
}
sink_->OnDroppedFrame(reason);
}
void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,