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_interpolator.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 AbsoluteCaptureTimeInterpolator::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 AbsoluteCaptureTimeInterpolator::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 AbsoluteCaptureTimeInterpolator::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