Update call expectations in ReceiveStatisticsProxy, add thread checks

Bug: chromium:1084619
Change-Id: If9042d44ad99eacd431ee2a5e84486cfaf282d7e
Tbr: stefan@webrtc.org
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/175658
Reviewed-by: Tommi <tommi@webrtc.org>
Commit-Queue: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31330}
diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc
index 944f97b..64d3699 100644
--- a/modules/video_coding/frame_buffer2.cc
+++ b/modules/video_coding/frame_buffer2.cc
@@ -63,19 +63,25 @@
       last_log_non_decoded_ms_(-kLogNonDecodedIntervalMs),
       add_rtt_to_playout_delay_(
           webrtc::field_trial::IsEnabled("WebRTC-AddRttToPlayoutDelay")),
-      rtt_mult_settings_(RttMultExperiment::GetRttMultValue()) {}
+      rtt_mult_settings_(RttMultExperiment::GetRttMultValue()) {
+  callback_checker_.Detach();
+}
 
-FrameBuffer::~FrameBuffer() {}
+FrameBuffer::~FrameBuffer() {
+  RTC_DCHECK_RUN_ON(&construction_checker_);
+}
 
 void FrameBuffer::NextFrame(
     int64_t max_wait_time_ms,
     bool keyframe_required,
     rtc::TaskQueue* callback_queue,
     std::function<void(std::unique_ptr<EncodedFrame>, ReturnReason)> handler) {
-  RTC_DCHECK_RUN_ON(callback_queue);
+  RTC_DCHECK_RUN_ON(&callback_checker_);
+  RTC_DCHECK(callback_queue->IsCurrent());
   TRACE_EVENT0("webrtc", "FrameBuffer::NextFrame");
   int64_t latest_return_time_ms =
       clock_->TimeInMilliseconds() + max_wait_time_ms;
+
   rtc::CritScope lock(&crit_);
   if (stopped_) {
     return;
@@ -93,6 +99,7 @@
   int64_t wait_ms = FindNextFrame(clock_->TimeInMilliseconds());
   callback_task_ = RepeatingTaskHandle::DelayedStart(
       callback_queue_->Get(), TimeDelta::Millis(wait_ms), [this] {
+        RTC_DCHECK_RUN_ON(&callback_checker_);
         // If this task has not been cancelled, we did not get any new frames
         // while waiting. Continue with frame delivery.
         rtc::CritScope lock(&crit_);
@@ -211,6 +218,7 @@
 }
 
 EncodedFrame* FrameBuffer::GetNextFrame() {
+  RTC_DCHECK_RUN_ON(&callback_checker_);
   int64_t now_ms = clock_->TimeInMilliseconds();
   // TODO(ilnik): remove |frames_out| use frames_to_decode_ directly.
   std::vector<EncodedFrame*> frames_out;
@@ -334,7 +342,10 @@
 void FrameBuffer::Stop() {
   TRACE_EVENT0("webrtc", "FrameBuffer::Stop");
   rtc::CritScope lock(&crit_);
+  if (stopped_)
+    return;
   stopped_ = true;
+
   CancelCallback();
 }
 
@@ -366,9 +377,11 @@
 }
 
 void FrameBuffer::CancelCallback() {
+  // Called from the callback queue or from within Stop().
   frame_handler_ = {};
   callback_task_.Stop();
   callback_queue_ = nullptr;
+  callback_checker_.Detach();
 }
 
 bool FrameBuffer::IsCompleteSuperFrame(const EncodedFrame& frame) {
diff --git a/modules/video_coding/frame_buffer2.h b/modules/video_coding/frame_buffer2.h
index 51f3820..d824ddf 100644
--- a/modules/video_coding/frame_buffer2.h
+++ b/modules/video_coding/frame_buffer2.h
@@ -28,6 +28,7 @@
 #include "rtc_base/event.h"
 #include "rtc_base/experiments/rtt_mult_experiment.h"
 #include "rtc_base/numerics/sequence_number_util.h"
+#include "rtc_base/synchronization/sequence_checker.h"
 #include "rtc_base/task_queue.h"
 #include "rtc_base/task_utils/repeating_task.h"
 #include "rtc_base/thread_annotations.h"
@@ -159,6 +160,9 @@
   EncodedFrame* CombineAndDeleteFrames(
       const std::vector<EncodedFrame*>& frames) const;
 
+  SequenceChecker construction_checker_;
+  SequenceChecker callback_checker_;
+
   // Stores only undecoded frames.
   FrameMap frames_ RTC_GUARDED_BY(crit_);
   DecodedFramesHistory decoded_frames_history_ RTC_GUARDED_BY(crit_);
diff --git a/video/receive_statistics_proxy2.cc b/video/receive_statistics_proxy2.cc
index 0ba4d5d..15d08c4 100644
--- a/video/receive_statistics_proxy2.cc
+++ b/video/receive_statistics_proxy2.cc
@@ -1002,7 +1002,8 @@
 }
 
 void ReceiveStatisticsProxy::OnDroppedFrames(uint32_t frames_dropped) {
-  RTC_DCHECK_RUN_ON(&decode_queue_);
+  // Can be called on either the decode queue or the worker thread
+  // See FrameBuffer2 for more details.
   worker_thread_->PostTask(ToQueuedTask(task_safety_, [frames_dropped, this]() {
     RTC_DCHECK_RUN_ON(&main_thread_);
     stats_.frames_dropped += frames_dropped;