Clear FrameBuffer if there were no frames received for 10 minutes
This is a workaround for the case when there are no video frames in a call for a very long time, such that RTP timestamps wraparound and FrameBuffer can't figure out if the frame is older or newer. Bug: webrtc:9974 Change-Id: Ie1eaa4938813dbbd637ddcbe7ff118ead2bfa4a9 Reviewed-on: https://webrtc-review.googlesource.com/c/109882 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25548}
This commit is contained in:

committed by
Commit Bot

parent
b768e8800f
commit
e6a2d94eca
@ -113,6 +113,9 @@ FrameBuffer::ReturnReason FrameBuffer::NextFrame(
|
||||
if (keyframe_required && !frame->is_keyframe())
|
||||
continue;
|
||||
|
||||
// TODO(https://bugs.webrtc.org/9974): consider removing this check
|
||||
// as it may make a stream undecodable after a very long delay between
|
||||
// frames.
|
||||
if (last_decoded_frame_timestamp_ &&
|
||||
AheadOf(*last_decoded_frame_timestamp_, frame->Timestamp())) {
|
||||
continue;
|
||||
@ -244,6 +247,11 @@ void FrameBuffer::Stop() {
|
||||
new_continuous_frame_event_.Set();
|
||||
}
|
||||
|
||||
void FrameBuffer::Clear() {
|
||||
rtc::CritScope lock(&crit_);
|
||||
ClearFramesAndHistory();
|
||||
}
|
||||
|
||||
void FrameBuffer::UpdateRtt(int64_t rtt_ms) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
jitter_estimator_->UpdateRtt(rtt_ms);
|
||||
|
@ -79,6 +79,9 @@ class FrameBuffer {
|
||||
// Updates the RTT for jitter buffer estimation.
|
||||
void UpdateRtt(int64_t rtt_ms);
|
||||
|
||||
// Clears the FrameBuffer, removing all the buffered frames.
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
struct FrameInfo {
|
||||
FrameInfo();
|
||||
|
@ -110,6 +110,11 @@ class NullVideoDecoder : public webrtc::VideoDecoder {
|
||||
const char* ImplementationName() const override { return "NullVideoDecoder"; }
|
||||
};
|
||||
|
||||
// TODO(https://bugs.webrtc.org/9974): Consider removing this workaround.
|
||||
// Maximum time between frames before resetting the FrameBuffer to avoid RTP
|
||||
// timestamps wraparound to affect FrameBuffer.
|
||||
constexpr int kInactiveStreamThresholdMs = 600000; // 10 minutes.
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
@ -373,6 +378,14 @@ void VideoReceiveStream::OnCompleteFrame(
|
||||
// partially enabled inter-layer prediction.
|
||||
frame->id.spatial_layer = 0;
|
||||
|
||||
// TODO(https://bugs.webrtc.org/9974): Consider removing this workaround.
|
||||
int64_t time_now_ms = rtc::TimeMillis();
|
||||
if (last_complete_frame_time_ms_ > 0 &&
|
||||
time_now_ms - last_complete_frame_time_ms_ > kInactiveStreamThresholdMs) {
|
||||
frame_buffer_->Clear();
|
||||
}
|
||||
last_complete_frame_time_ms_ = time_now_ms;
|
||||
|
||||
int64_t last_continuous_pid = frame_buffer_->InsertFrame(std::move(frame));
|
||||
if (last_continuous_pid != -1)
|
||||
rtp_video_stream_receiver_.FrameContinuous(last_continuous_pid);
|
||||
|
@ -146,6 +146,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
||||
bool frame_decoded_ = false;
|
||||
|
||||
int64_t last_keyframe_request_ms_ = 0;
|
||||
int64_t last_complete_frame_time_ms_ = 0;
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user