Use Timestamp and TimeDelta in VCMTiming

* Switches TimestampExtrapolator to use Timestamp as well.

Bug: webrtc:13589
Change-Id: I042be5d693068553d2e8eb92fa532092d77bd7ef
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/249993
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Commit-Queue: Evan Shrubsole <eshr@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36112}
diff --git a/video/frame_buffer_proxy.cc b/video/frame_buffer_proxy.cc
index 31aa86f..d277a36 100644
--- a/video/frame_buffer_proxy.cc
+++ b/video/frame_buffer_proxy.cc
@@ -148,7 +148,7 @@
         contentType(frame.contentType()),
         delayed_by_retransmission(frame.delayed_by_retransmission()),
         rtp_timestamp(frame.Timestamp()),
-        receive_time(frame.ReceivedTime()) {}
+        receive_time_ms(frame.ReceivedTime()) {}
 
   const bool is_last_spatial_layer;
   const bool is_keyframe;
@@ -156,7 +156,7 @@
   const VideoContentType contentType;
   const bool delayed_by_retransmission;
   const uint32_t rtp_timestamp;
-  const int64_t receive_time;
+  const int64_t receive_time_ms;
 };
 
 // Encapsulates use of the new frame buffer for use in VideoReceiveStream. This
@@ -247,9 +247,12 @@
     if (complete_units < buffer_->GetTotalNumberOfContinuousTemporalUnits()) {
       stats_proxy_->OnCompleteFrame(metadata.is_keyframe, metadata.size,
                                     metadata.contentType);
-      if (!metadata.delayed_by_retransmission)
+      RTC_DCHECK_GE(metadata.receive_time_ms, 0)
+          << "Frame receive time must be positive for received frames, was "
+          << metadata.receive_time_ms << ".";
+      if (!metadata.delayed_by_retransmission && metadata.receive_time_ms >= 0)
         timing_->IncomingTimestamp(metadata.rtp_timestamp,
-                                   metadata.receive_time);
+                                   Timestamp::Millis(metadata.receive_time_ms));
       MaybeScheduleFrameForRelease();
     }
 
@@ -293,7 +296,7 @@
 
     timeout_tracker_.OnEncodedFrameReleased();
 
-    int64_t now_ms = clock_->TimeInMilliseconds();
+    Timestamp now = clock_->CurrentTime();
     bool superframe_delayed_by_retransmission = false;
     size_t superframe_size = 0;
     const EncodedFrame& first_frame = *frames.front();
@@ -303,12 +306,11 @@
       keyframe_required_ = false;
 
     // Gracefully handle bad RTP timestamps and render time issues.
-    if (FrameHasBadRenderTiming(render_time.ms(), now_ms,
+    if (FrameHasBadRenderTiming(render_time, now,
                                 timing_->TargetVideoDelay())) {
       jitter_estimator_.Reset();
       timing_->Reset();
-      render_time = Timestamp::Millis(
-          timing_->RenderTimeMs(first_frame.Timestamp(), now_ms));
+      render_time = timing_->RenderTime(first_frame.Timestamp(), now);
     }
 
     for (std::unique_ptr<EncodedFrame>& frame : frames) {
@@ -334,9 +336,9 @@
         rtt_mult = rtt_mult_settings_->rtt_mult_setting;
         rtt_mult_add_cap_ms = rtt_mult_settings_->rtt_mult_add_cap_ms;
       }
-      timing_->SetJitterDelay(
-          jitter_estimator_.GetJitterEstimate(rtt_mult, rtt_mult_add_cap_ms));
-      timing_->UpdateCurrentDelay(render_time.ms(), now_ms);
+      timing_->SetJitterDelay(TimeDelta::Millis(
+          jitter_estimator_.GetJitterEstimate(rtt_mult, rtt_mult_add_cap_ms)));
+      timing_->UpdateCurrentDelay(render_time, now);
     } else if (RttMultExperiment::RttMultEnabled()) {
       jitter_estimator_.FrameNacked();
     }
@@ -349,7 +351,7 @@
     std::unique_ptr<EncodedFrame> frame =
         CombineAndDeleteFrames(std::move(frames));
 
-    timing_->SetLastDecodeScheduledTimestamp(now_ms);
+    timing_->SetLastDecodeScheduledTimestamp(now);
 
     decoder_ready_for_new_frame_ = false;
     // VideoReceiveStream2 wants frames on the decoder thread.
@@ -399,18 +401,18 @@
   }
 
   void UpdateJitterDelay() {
-    int max_decode_ms;
-    int current_delay_ms;
-    int target_delay_ms;
-    int jitter_buffer_ms;
-    int min_playout_delay_ms;
-    int render_delay_ms;
-    if (timing_->GetTimings(&max_decode_ms, &current_delay_ms, &target_delay_ms,
-                            &jitter_buffer_ms, &min_playout_delay_ms,
-                            &render_delay_ms)) {
+    TimeDelta max_decode = TimeDelta::Zero();
+    TimeDelta current_delay = TimeDelta::Zero();
+    TimeDelta target_delay = TimeDelta::Zero();
+    TimeDelta jitter_buffer = TimeDelta::Zero();
+    TimeDelta min_playout_delay = TimeDelta::Zero();
+    TimeDelta render_delay = TimeDelta::Zero();
+    if (timing_->GetTimings(&max_decode, &current_delay, &target_delay,
+                            &jitter_buffer, &min_playout_delay,
+                            &render_delay)) {
       stats_proxy_->OnFrameBufferTimingsUpdated(
-          max_decode_ms, current_delay_ms, target_delay_ms, jitter_buffer_ms,
-          min_playout_delay_ms, render_delay_ms);
+          max_decode.ms(), current_delay.ms(), target_delay.ms(),
+          jitter_buffer.ms(), min_playout_delay.ms(), render_delay.ms());
     }
   }
 
@@ -437,8 +439,8 @@
       }
       // Found keyframe - decode right away.
       if (next_frame.front()->is_keyframe()) {
-        auto render_time = Timestamp::Millis(timing_->RenderTimeMs(
-            next_frame.front()->Timestamp(), clock_->TimeInMilliseconds()));
+        auto render_time = timing_->RenderTime(next_frame.front()->Timestamp(),
+                                               clock_->CurrentTime());
         OnFrameReady(std::move(next_frame), render_time);
         return;
       }
diff --git a/video/frame_buffer_proxy_unittest.cc b/video/frame_buffer_proxy_unittest.cc
index 81e5bd2..e7307fd 100644
--- a/video/frame_buffer_proxy_unittest.cc
+++ b/video/frame_buffer_proxy_unittest.cc
@@ -233,7 +233,7 @@
                                                       kMaxWaitForFrame,
                                                       &decode_sync_)) {
     // Avoid starting with negative render times.
-    timing_.set_min_playout_delay(10);
+    timing_.set_min_playout_delay(TimeDelta::Millis(10));
 
     ON_CALL(stats_callback_, OnDroppedFrames)
         .WillByDefault(
@@ -631,8 +631,7 @@
   EXPECT_CALL(stats_callback_, OnFrameBufferTimingsUpdated);
 
   // Fake timing having received decoded frame.
-  timing_.StopDecodeTimer(clock_->TimeInMicroseconds() + 1,
-                          clock_->TimeInMilliseconds());
+  timing_.StopDecodeTimer(TimeDelta::Millis(1), clock_->CurrentTime());
   StartNextDecodeForceKeyframe();
   proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build());
   EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0)));
@@ -775,8 +774,8 @@
        FramesDecodedInstantlyWithLowLatencyRendering) {
   // Initial keyframe.
   StartNextDecodeForceKeyframe();
-  timing_.set_min_playout_delay(0);
-  timing_.set_max_playout_delay(10);
+  timing_.set_min_playout_delay(TimeDelta::Zero());
+  timing_.set_max_playout_delay(TimeDelta::Millis(10));
   auto frame = Builder().Id(0).Time(0).AsLast().Build();
   // Playout delay of 0 implies low-latency rendering.
   frame->SetPlayoutDelay({0, 10});
@@ -798,8 +797,8 @@
 TEST_P(LowLatencyFrameBufferProxyTest, ZeroPlayoutDelayFullQueue) {
   // Initial keyframe.
   StartNextDecodeForceKeyframe();
-  timing_.set_min_playout_delay(0);
-  timing_.set_max_playout_delay(10);
+  timing_.set_min_playout_delay(TimeDelta::Zero());
+  timing_.set_max_playout_delay(TimeDelta::Millis(10));
   auto frame = Builder().Id(0).Time(0).AsLast().Build();
   // Playout delay of 0 implies low-latency rendering.
   frame->SetPlayoutDelay({0, 10});
@@ -822,8 +821,8 @@
 TEST_P(LowLatencyFrameBufferProxyTest, MinMaxDelayZeroLowLatencyMode) {
   // Initial keyframe.
   StartNextDecodeForceKeyframe();
-  timing_.set_min_playout_delay(0);
-  timing_.set_max_playout_delay(0);
+  timing_.set_min_playout_delay(TimeDelta::Zero());
+  timing_.set_max_playout_delay(TimeDelta::Zero());
   auto frame = Builder().Id(0).Time(0).AsLast().Build();
   // Playout delay of 0 implies low-latency rendering.
   frame->SetPlayoutDelay({0, 0});
diff --git a/video/frame_decode_timing.cc b/video/frame_decode_timing.cc
index ddc6030..c683834 100644
--- a/video/frame_decode_timing.cc
+++ b/video/frame_decode_timing.cc
@@ -30,10 +30,9 @@
                                         uint32_t last_temporal_unit_rtp,
                                         bool too_many_frames_queued) {
   const Timestamp now = clock_->CurrentTime();
-  Timestamp render_time = Timestamp::Millis(
-      timing_->RenderTimeMs(next_temporal_unit_rtp, now.ms()));
-  TimeDelta max_wait = TimeDelta::Millis(timing_->MaxWaitingTime(
-      render_time.ms(), now.ms(), too_many_frames_queued));
+  Timestamp render_time = timing_->RenderTime(next_temporal_unit_rtp, now);
+  TimeDelta max_wait =
+      timing_->MaxWaitingTime(render_time, now, too_many_frames_queued);
 
   // If the delay is not too far in the past, or this is the last decodable
   // frame then it is the best frame to be decoded. Otherwise, fast-forward
diff --git a/video/frame_decode_timing_unittest.cc b/video/frame_decode_timing_unittest.cc
index ac5bf9e..0d99847 100644
--- a/video/frame_decode_timing_unittest.cc
+++ b/video/frame_decode_timing_unittest.cc
@@ -32,20 +32,18 @@
  public:
   explicit FakeVCMTiming(Clock* clock) : webrtc::VCMTiming(clock) {}
 
-  int64_t RenderTimeMs(uint32_t frame_timestamp,
-                       int64_t now_ms) const override {
+  Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
     RTC_DCHECK(render_time_map_.contains(frame_timestamp));
     auto it = render_time_map_.find(frame_timestamp);
-    return it->second.ms();
+    return it->second;
   }
 
-  int64_t MaxWaitingTime(int64_t render_time_ms,
-                         int64_t now_ms,
-                         bool too_many_frames_queued) const override {
-    auto render_time = Timestamp::Millis(render_time_ms);
+  TimeDelta MaxWaitingTime(Timestamp render_time,
+                           Timestamp now,
+                           bool too_many_frames_queued) const override {
     RTC_DCHECK(wait_time_map_.contains(render_time));
     auto it = wait_time_map_.find(render_time);
-    return it->second.ms();
+    return it->second;
   }
 
   void SetTimes(uint32_t frame_timestamp,
diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc
index 5436c01..290180b 100644
--- a/video/video_receive_stream2.cc
+++ b/video/video_receive_stream2.cc
@@ -269,7 +269,7 @@
     decoder_payload_types.insert(decoder.payload_type);
   }
 
-  timing_->set_render_delay(config_.render_delay_ms);
+  timing_->set_render_delay(TimeDelta::Millis(config_.render_delay_ms));
 
   frame_buffer_ = FrameBufferProxy::CreateFromFieldTrial(
       clock_, call_->worker_thread(), timing_.get(), &stats_proxy_,
@@ -710,7 +710,7 @@
   if (!info)
     return absl::nullopt;
 
-  info->current_delay_ms = timing_->TargetVideoDelay();
+  info->current_delay_ms = timing_->TargetVideoDelay().ms();
   return info;
 }
 
@@ -970,7 +970,7 @@
       std::max({frame_minimum_playout_delay_ms_, base_minimum_playout_delay_ms_,
                 syncable_minimum_playout_delay_ms_});
   if (minimum_delay_ms >= 0) {
-    timing_->set_min_playout_delay(minimum_delay_ms);
+    timing_->set_min_playout_delay(TimeDelta::Millis(minimum_delay_ms));
     if (frame_minimum_playout_delay_ms_ == 0 &&
         frame_maximum_playout_delay_ms_ > 0 && low_latency_renderer_enabled_) {
       // TODO(kron): Estimate frame rate from video stream.
@@ -991,7 +991,7 @@
 
   const int maximum_delay_ms = frame_maximum_playout_delay_ms_;
   if (maximum_delay_ms >= 0) {
-    timing_->set_max_playout_delay(maximum_delay_ms);
+    timing_->set_max_playout_delay(TimeDelta::Millis(maximum_delay_ms));
   }
 }
 
diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc
index 3c6640a..213df38 100644
--- a/video/video_receive_stream2_unittest.cc
+++ b/video/video_receive_stream2_unittest.cc
@@ -163,30 +163,30 @@
   test_frame->SetPlayoutDelay(kPlayoutDelayMs);
 
   video_receive_stream_->OnCompleteFrame(std::move(test_frame));
-  EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
-  EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
+  EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
+  EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
 
   // Check that the biggest minimum delay is chosen.
   video_receive_stream_->SetMinimumPlayoutDelay(400);
-  EXPECT_EQ(400, timing_->min_playout_delay());
+  EXPECT_EQ(400, timing_->min_playout_delay().ms());
 
   // Check base minimum delay validation.
   EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
   EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
   EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
-  EXPECT_EQ(500, timing_->min_playout_delay());
+  EXPECT_EQ(500, timing_->min_playout_delay().ms());
 
   // Check that intermidiate values are remembered and the biggest remembered
   // is chosen.
   video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
-  EXPECT_EQ(400, timing_->min_playout_delay());
+  EXPECT_EQ(400, timing_->min_playout_delay().ms());
 
   video_receive_stream_->SetMinimumPlayoutDelay(0);
-  EXPECT_EQ(123, timing_->min_playout_delay());
+  EXPECT_EQ(123, timing_->min_playout_delay().ms());
 }
 
 TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
-  const int default_max_playout_latency = timing_->max_playout_delay();
+  const TimeDelta default_max_playout_latency = timing_->max_playout_delay();
   const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
 
   std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
@@ -196,13 +196,13 @@
   video_receive_stream_->OnCompleteFrame(std::move(test_frame));
 
   // Ensure that -1 preserves default maximum value from `timing_`.
-  EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
-  EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
+  EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
+  EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
   EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
 }
 
 TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
-  const int default_min_playout_latency = timing_->min_playout_delay();
+  const TimeDelta default_min_playout_latency = timing_->min_playout_delay();
   const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
 
   std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
@@ -212,8 +212,8 @@
   video_receive_stream_->OnCompleteFrame(std::move(test_frame));
 
   // Ensure that -1 preserves default minimum value from `timing_`.
-  EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
-  EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
+  EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
+  EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
   EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
 }
 
diff --git a/video/video_stream_decoder_impl.cc b/video/video_stream_decoder_impl.cc
index bbd67ee..907b8b0 100644
--- a/video/video_stream_decoder_impl.cc
+++ b/video/video_stream_decoder_impl.cc
@@ -70,11 +70,11 @@
 }
 
 void VideoStreamDecoderImpl::SetMinPlayoutDelay(TimeDelta min_delay) {
-  timing_.set_min_playout_delay(min_delay.ms());
+  timing_.set_min_playout_delay(min_delay);
 }
 
 void VideoStreamDecoderImpl::SetMaxPlayoutDelay(TimeDelta max_delay) {
-  timing_.set_max_playout_delay(max_delay.ms());
+  timing_.set_max_playout_delay(max_delay);
 }
 
 VideoDecoder* VideoStreamDecoderImpl::GetDecoder(int payload_type) {
@@ -258,7 +258,8 @@
          Timestamp::Millis(frame_info->decode_start_time_ms +
                            *decode_time_ms)});
     decoded_image.set_timestamp_us(frame_info->render_time_us);
-    timing_.StopDecodeTimer(*decode_time_ms, decode_stop_time_ms);
+    timing_.StopDecodeTimer(TimeDelta::Millis(*decode_time_ms),
+                            Timestamp::Millis(decode_stop_time_ms));
 
     callbacks_->OnDecodedFrame(decoded_image, callback_info);
   });