From 95e9754e4055ba0190a71dc4c0549182ae362dd4 Mon Sep 17 00:00:00 2001 From: stefan Date: Tue, 23 May 2017 09:52:18 -0700 Subject: [PATCH] More gracefully handle timing errors, such as unexpected changes in the rtp timestamp. BUG=webrtc:7682 Review-Url: https://codereview.webrtc.org/2898763005 Cr-Commit-Position: refs/heads/master@{#18245} --- webrtc/modules/video_coding/frame_buffer2.cc | 30 ++++++++++++++++++++ webrtc/modules/video_coding/frame_buffer2.h | 3 ++ 2 files changed, 33 insertions(+) diff --git a/webrtc/modules/video_coding/frame_buffer2.cc b/webrtc/modules/video_coding/frame_buffer2.cc index 584c2f03c4..de96a52b1b 100644 --- a/webrtc/modules/video_coding/frame_buffer2.cc +++ b/webrtc/modules/video_coding/frame_buffer2.cc @@ -141,6 +141,13 @@ FrameBuffer::ReturnReason FrameBuffer::NextFrame( timing_->UpdateCurrentDelay(frame->RenderTime(), now_ms); } + // Gracefully handle bad RTP timestamps and render time issues. + if (HasBadRenderTiming(*frame, now_ms)) { + jitter_estimator_->Reset(); + timing_->Reset(); + frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); + } + UpdateJitterDelay(); PropagateDecodability(next_frame_it_->second); @@ -189,6 +196,29 @@ FrameBuffer::ReturnReason FrameBuffer::NextFrame( return kTimeout; } +bool FrameBuffer::HasBadRenderTiming(const FrameObject& frame, int64_t now_ms) { + // Assume that render timing errors are due to changes in the video stream. + int64_t render_time_ms = frame.RenderTimeMs(); + const int64_t kMaxVideoDelayMs = 10000; + if (render_time_ms < 0) { + return true; + } + if (std::abs(render_time_ms - now_ms) > kMaxVideoDelayMs) { + int frame_delay = static_cast(std::abs(render_time_ms - now_ms)); + LOG(LS_WARNING) << "A frame about to be decoded is out of the configured " + << "delay bounds (" << frame_delay << " > " + << kMaxVideoDelayMs + << "). Resetting the video jitter buffer."; + return true; + } + if (static_cast(timing_->TargetVideoDelay()) > kMaxVideoDelayMs) { + LOG(LS_WARNING) << "The video target delay has grown larger than " + << kMaxVideoDelayMs << " ms."; + return true; + } + return false; +} + void FrameBuffer::SetProtectionMode(VCMVideoProtection mode) { TRACE_EVENT0("webrtc", "FrameBuffer::SetProtectionMode"); rtc::CritScope lock(&crit_); diff --git a/webrtc/modules/video_coding/frame_buffer2.h b/webrtc/modules/video_coding/frame_buffer2.h index 4695631ec5..6ce3b4be57 100644 --- a/webrtc/modules/video_coding/frame_buffer2.h +++ b/webrtc/modules/video_coding/frame_buffer2.h @@ -150,6 +150,9 @@ class FrameBuffer { void ClearFramesAndHistory() EXCLUSIVE_LOCKS_REQUIRED(crit_); + bool HasBadRenderTiming(const FrameObject& frame, int64_t now_ms) + EXCLUSIVE_LOCKS_REQUIRED(crit_); + FrameMap frames_ GUARDED_BY(crit_); rtc::CriticalSection crit_;