1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/rtp_rtcp/source/absolute_capture_time_sender.h"
12 
13 #include <limits>
14 
15 #include "modules/rtp_rtcp/source/absolute_capture_time_receiver.h"
16 #include "system_wrappers/include/ntp_time.h"
17 
18 namespace webrtc {
19 namespace {
20 
21 constexpr Timestamp kInvalidLastSendTime = Timestamp::MinusInfinity();
22 
23 }  // namespace
24 
25 constexpr TimeDelta AbsoluteCaptureTimeSender::kInterpolationMaxInterval;
26 constexpr TimeDelta AbsoluteCaptureTimeSender::kInterpolationMaxError;
27 
28 static_assert(
29     AbsoluteCaptureTimeReceiver::kInterpolationMaxInterval >=
30         AbsoluteCaptureTimeSender::kInterpolationMaxInterval,
31     "Receivers should be as willing to interpolate timestamps as senders.");
32 
AbsoluteCaptureTimeSender(Clock * clock)33 AbsoluteCaptureTimeSender::AbsoluteCaptureTimeSender(Clock* clock)
34     : clock_(clock), last_send_time_(kInvalidLastSendTime) {}
35 
GetSource(uint32_t ssrc,rtc::ArrayView<const uint32_t> csrcs)36 uint32_t AbsoluteCaptureTimeSender::GetSource(
37     uint32_t ssrc,
38     rtc::ArrayView<const uint32_t> csrcs) {
39   return AbsoluteCaptureTimeReceiver::GetSource(ssrc, csrcs);
40 }
41 
OnSendPacket(uint32_t source,uint32_t rtp_timestamp,uint32_t rtp_clock_frequency,uint64_t absolute_capture_timestamp,absl::optional<int64_t> estimated_capture_clock_offset)42 absl::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket(
43     uint32_t source,
44     uint32_t rtp_timestamp,
45     uint32_t rtp_clock_frequency,
46     uint64_t absolute_capture_timestamp,
47     absl::optional<int64_t> estimated_capture_clock_offset) {
48   const Timestamp send_time = clock_->CurrentTime();
49 
50   MutexLock lock(&mutex_);
51 
52   if (!ShouldSendExtension(send_time, source, rtp_timestamp,
53                            rtp_clock_frequency, absolute_capture_timestamp,
54                            estimated_capture_clock_offset)) {
55     return absl::nullopt;
56   }
57 
58   last_source_ = source;
59   last_rtp_timestamp_ = rtp_timestamp;
60   last_rtp_clock_frequency_ = rtp_clock_frequency;
61   last_absolute_capture_timestamp_ = absolute_capture_timestamp;
62   last_estimated_capture_clock_offset_ = estimated_capture_clock_offset;
63 
64   last_send_time_ = send_time;
65 
66   AbsoluteCaptureTime extension;
67   extension.absolute_capture_timestamp = absolute_capture_timestamp;
68   extension.estimated_capture_clock_offset = estimated_capture_clock_offset;
69   return extension;
70 }
71 
ShouldSendExtension(Timestamp send_time,uint32_t source,uint32_t rtp_timestamp,uint32_t rtp_clock_frequency,uint64_t absolute_capture_timestamp,absl::optional<int64_t> estimated_capture_clock_offset) const72 bool AbsoluteCaptureTimeSender::ShouldSendExtension(
73     Timestamp send_time,
74     uint32_t source,
75     uint32_t rtp_timestamp,
76     uint32_t rtp_clock_frequency,
77     uint64_t absolute_capture_timestamp,
78     absl::optional<int64_t> estimated_capture_clock_offset) const {
79   // Should if we've never sent anything before.
80   if (last_send_time_ == kInvalidLastSendTime) {
81     return true;
82   }
83 
84   // Should if the last sent extension is too old.
85   if ((send_time - last_send_time_) > kInterpolationMaxInterval) {
86     return true;
87   }
88 
89   // Should if the source has changed.
90   if (last_source_ != source) {
91     return true;
92   }
93 
94   // Should if the RTP clock frequency has changed.
95   if (last_rtp_clock_frequency_ != rtp_clock_frequency) {
96     return true;
97   }
98 
99   // Should if the RTP clock frequency is invalid.
100   if (rtp_clock_frequency <= 0) {
101     return true;
102   }
103 
104   // Should if the estimated capture clock offset has changed.
105   if (last_estimated_capture_clock_offset_ != estimated_capture_clock_offset) {
106     return true;
107   }
108 
109   // Should if interpolation would introduce too much error.
110   const uint64_t interpolated_absolute_capture_timestamp =
111       AbsoluteCaptureTimeReceiver::InterpolateAbsoluteCaptureTimestamp(
112           rtp_timestamp, rtp_clock_frequency, last_rtp_timestamp_,
113           last_absolute_capture_timestamp_);
114   const int64_t interpolation_error_ms = UQ32x32ToInt64Ms(std::min(
115       interpolated_absolute_capture_timestamp - absolute_capture_timestamp,
116       absolute_capture_timestamp - interpolated_absolute_capture_timestamp));
117   if (interpolation_error_ms > kInterpolationMaxError.ms()) {
118     return true;
119   }
120 
121   return false;
122 }
123 
124 }  // namespace webrtc
125