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}
diff --git a/webrtc/modules/video_coding/frame_buffer2.cc b/webrtc/modules/video_coding/frame_buffer2.cc
index 584c2f0..de96a52 100644
--- a/webrtc/modules/video_coding/frame_buffer2.cc
+++ b/webrtc/modules/video_coding/frame_buffer2.cc
@@ -141,6 +141,13 @@
         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 @@
   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<int>(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<int>(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 4695631..6ce3b4b 100644
--- a/webrtc/modules/video_coding/frame_buffer2.h
+++ b/webrtc/modules/video_coding/frame_buffer2.h
@@ -150,6 +150,9 @@
 
   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_;