VideoStreamDecoderImpl implementation, part 1.

In this CL the OnFrame function is implemented.

Bug: webrtc:8909
Change-Id: I68488a033e86eadd0b16d091faad14e9cda7cc36
Reviewed-on: https://webrtc-review.googlesource.com/64121
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22583}
diff --git a/api/video/video_stream_decoder.h b/api/video/video_stream_decoder.h
index 0f04827..1c4c5ff 100644
--- a/api/video/video_stream_decoder.h
+++ b/api/video/video_stream_decoder.h
@@ -21,10 +21,6 @@
 #include "api/video_codecs/video_decoder_factory.h"
 
 namespace webrtc {
-// TODO(philipel): #include instead of forward declare when the relevant CL has
-//                 landed.
-class FrameKey;
-
 // NOTE: This class is still under development and may change without notice.
 class VideoStreamDecoder {
  public:
@@ -36,7 +32,8 @@
     virtual void OnNonDecodableState() = 0;
 
     // Called with the last continuous frame.
-    virtual void OnContinuousUntil(const FrameKey& key) = 0;
+    virtual void OnContinuousUntil(
+        const video_coding::VideoLayerFrameId& key) = 0;
 
     // Called with the decoded frame.
     virtual void OnDecodedFrame(VideoFrame decodedImage,
diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc
index 3a3a727..86f6e42 100644
--- a/modules/video_coding/frame_buffer2.cc
+++ b/modules/video_coding/frame_buffer2.cc
@@ -588,7 +588,7 @@
 void FrameBuffer::UpdateTimingFrameInfo() {
   TRACE_EVENT0("webrtc", "FrameBuffer::UpdateTimingFrameInfo");
   rtc::Optional<TimingFrameInfo> info = timing_->GetTimingFrameInfo();
-  if (info)
+  if (info && stats_callback_)
     stats_callback_->OnTimingFrameInfoUpdated(*info);
 }
 
diff --git a/modules/video_coding/frame_buffer2.h b/modules/video_coding/frame_buffer2.h
index c05fb8a..1197e82 100644
--- a/modules/video_coding/frame_buffer2.h
+++ b/modules/video_coding/frame_buffer2.h
@@ -47,6 +47,7 @@
 
   // Insert a frame into the frame buffer. Returns the picture id
   // of the last continuous frame or -1 if there is no continuous frame.
+  // TODO(philipel): Return a VideoLayerFrameId and not only the picture id.
   int64_t InsertFrame(std::unique_ptr<EncodedFrame> frame);
 
   // Get the next frame for decoding. Will return at latest after
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 50deea8..8a996a3 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -116,7 +116,10 @@
     "../api:video_frame_api",
     "../api:video_stream_decoder",
     "../api/video_codecs:video_codecs_api",
+    "../modules/video_coding:video_coding",
     "../rtc_base:rtc_base_approved",
+    "../rtc_base:rtc_task_queue_api",
+    "../system_wrappers:system_wrappers",
   ]
 
   if (!build_with_chromium && is_clang) {
diff --git a/video/video_stream_decoder_impl.cc b/video/video_stream_decoder_impl.cc
index 5eca7d2..6d262b6 100644
--- a/video/video_stream_decoder_impl.cc
+++ b/video/video_stream_decoder_impl.cc
@@ -10,19 +10,61 @@
 
 #include "video/video_stream_decoder_impl.h"
 
+#include "rtc_base/logging.h"
 #include "rtc_base/ptr_util.h"
 
 namespace webrtc {
+
 VideoStreamDecoderImpl::VideoStreamDecoderImpl(
     VideoStreamDecoder::Callbacks* callbacks,
     VideoDecoderFactory* decoder_factory,
     std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings)
     : callbacks_(callbacks),
       decoder_factory_(decoder_factory),
-      decoder_settings_(std::move(decoder_settings)) {}
+      decoder_settings_(std::move(decoder_settings)),
+      bookkeeping_queue_("video_stream_decoder_bookkeeping_queue"),
+      jitter_estimator_(Clock::GetRealTimeClock()),
+      timing_(Clock::GetRealTimeClock()),
+      frame_buffer_(Clock::GetRealTimeClock(),
+                    &jitter_estimator_,
+                    &timing_,
+                    nullptr) {}
 
-VideoStreamDecoderImpl::~VideoStreamDecoderImpl() {}
+VideoStreamDecoderImpl::~VideoStreamDecoderImpl() {
+  frame_buffer_.Stop();
+}
 
 void VideoStreamDecoderImpl::OnFrame(
-    std::unique_ptr<video_coding::EncodedFrame> frame) {}
+    std::unique_ptr<video_coding::EncodedFrame> frame) {
+  if (!bookkeeping_queue_.IsCurrent()) {
+    struct OnFrameTask : rtc::QueuedTask {
+      OnFrameTask(std::unique_ptr<video_coding::EncodedFrame> frame,
+                  VideoStreamDecoderImpl* video_stream_decoder)
+          : frame_(std::move(frame)),
+            video_stream_decoder_(video_stream_decoder) {}
+
+      bool Run() {
+        video_stream_decoder_->OnFrame(std::move(frame_));
+        return true;
+      }
+
+      std::unique_ptr<video_coding::EncodedFrame> frame_;
+      VideoStreamDecoderImpl* video_stream_decoder_;
+    };
+
+    bookkeeping_queue_.PostTask(
+        rtc::MakeUnique<OnFrameTask>(std::move(frame), this));
+    return;
+  }
+
+  RTC_DCHECK_RUN_ON(&bookkeeping_queue_);
+
+  uint64_t continuous_pid = frame_buffer_.InsertFrame(std::move(frame));
+  video_coding::VideoLayerFrameId continuous_id(continuous_pid, 0);
+  if (last_continuous_id_ < continuous_id) {
+    last_continuous_id_ = continuous_id;
+    callbacks_->OnContinuousUntil(last_continuous_id_);
+  }
+}
+
 }  // namespace webrtc
diff --git a/video/video_stream_decoder_impl.h b/video/video_stream_decoder_impl.h
index f44913b..97de050 100644
--- a/video/video_stream_decoder_impl.h
+++ b/video/video_stream_decoder_impl.h
@@ -11,17 +11,17 @@
 #ifndef VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
 #define VIDEO_VIDEO_STREAM_DECODER_IMPL_H_
 
-#include <functional>
 #include <map>
 #include <memory>
 #include <utility>
 
-#include "api/optional.h"
-#include "api/video/encoded_frame.h"
-#include "api/video/video_frame.h"
 #include "api/video/video_stream_decoder.h"
-#include "api/video_codecs/sdp_video_format.h"
-#include "api/video_codecs/video_decoder_factory.h"
+#include "modules/video_coding/frame_buffer2.h"
+#include "modules/video_coding/jitter_estimator.h"
+#include "modules/video_coding/timing.h"
+#include "rtc_base/task_queue.h"
+#include "rtc_base/thread_checker.h"
+#include "system_wrappers/include/clock.h"
 
 namespace webrtc {
 
@@ -45,9 +45,21 @@
                rtc::Optional<int32_t> decode_time_ms,
                rtc::Optional<uint8_t> qp) override;
 
-  VideoStreamDecoder::Callbacks* callbacks_;
-  VideoDecoderFactory* decoder_factory_;
+  VideoStreamDecoder::Callbacks* const callbacks_
+      RTC_PT_GUARDED_BY(bookkeeping_queue_);
+  VideoDecoderFactory* const decoder_factory_;
   std::map<int, std::pair<SdpVideoFormat, int>> decoder_settings_;
+
+  // The |bookkeeping_queue_| is used to:
+  //  - Make |callbacks_|.
+  //  - Insert/extract frames from the |frame_buffer_|
+  //  - Synchronize with whatever thread that makes the Decoded callback.
+  rtc::TaskQueue bookkeeping_queue_;
+
+  VCMJitterEstimator jitter_estimator_;
+  VCMTiming timing_;
+  video_coding::FrameBuffer frame_buffer_;
+  video_coding::VideoLayerFrameId last_continuous_id_;
 };
 
 }  // namespace webrtc