absolute_capture_time_sender.cc (4505B)
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 <algorithm> 14 #include <cstdint> 15 #include <optional> 16 17 #include "api/array_view.h" 18 #include "api/rtp_headers.h" 19 #include "api/units/timestamp.h" 20 #include "modules/rtp_rtcp/source/absolute_capture_time_interpolator.h" 21 #include "system_wrappers/include/clock.h" 22 #include "system_wrappers/include/ntp_time.h" 23 24 namespace webrtc { 25 26 static_assert( 27 AbsoluteCaptureTimeInterpolator::kInterpolationMaxInterval >= 28 AbsoluteCaptureTimeSender::kInterpolationMaxInterval, 29 "Receivers should be as willing to interpolate timestamps as senders."); 30 31 AbsoluteCaptureTimeSender::AbsoluteCaptureTimeSender(Clock* clock) 32 : clock_(clock) {} 33 34 uint32_t AbsoluteCaptureTimeSender::GetSource(uint32_t ssrc, 35 ArrayView<const uint32_t> csrcs) { 36 return AbsoluteCaptureTimeInterpolator::GetSource(ssrc, csrcs); 37 } 38 39 std::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket( 40 uint32_t source, 41 uint32_t rtp_timestamp, 42 uint32_t rtp_clock_frequency, 43 uint64_t absolute_capture_timestamp, 44 std::optional<int64_t> estimated_capture_clock_offset) { 45 return OnSendPacket(source, rtp_timestamp, rtp_clock_frequency, 46 NtpTime(absolute_capture_timestamp), 47 estimated_capture_clock_offset, /*force=*/false); 48 } 49 50 std::optional<AbsoluteCaptureTime> AbsoluteCaptureTimeSender::OnSendPacket( 51 uint32_t source, 52 uint32_t rtp_timestamp, 53 int rtp_clock_frequency_hz, 54 NtpTime absolute_capture_time, 55 std::optional<int64_t> estimated_capture_clock_offset, 56 bool force) { 57 Timestamp send_time = clock_->CurrentTime(); 58 if (!(force || ShouldSendExtension( 59 send_time, source, rtp_timestamp, rtp_clock_frequency_hz, 60 absolute_capture_time, estimated_capture_clock_offset))) { 61 return std::nullopt; 62 } 63 64 last_source_ = source; 65 last_rtp_timestamp_ = rtp_timestamp; 66 last_rtp_clock_frequency_hz_ = rtp_clock_frequency_hz; 67 last_absolute_capture_time_ = absolute_capture_time; 68 last_estimated_capture_clock_offset_ = estimated_capture_clock_offset; 69 last_send_time_ = send_time; 70 71 return AbsoluteCaptureTime{ 72 .absolute_capture_timestamp = uint64_t{absolute_capture_time}, 73 .estimated_capture_clock_offset = estimated_capture_clock_offset, 74 }; 75 } 76 77 bool AbsoluteCaptureTimeSender::ShouldSendExtension( 78 Timestamp send_time, 79 uint32_t source, 80 uint32_t rtp_timestamp, 81 int rtp_clock_frequency_hz, 82 NtpTime absolute_capture_time, 83 std::optional<int64_t> estimated_capture_clock_offset) const { 84 // Should if the last sent extension is too old, in particular if we've never 85 // sent anything before. 86 if (send_time - last_send_time_ > kInterpolationMaxInterval) { 87 return true; 88 } 89 90 // Should if the source has changed. 91 if (last_source_ != source) { 92 return true; 93 } 94 95 // Should if the RTP clock frequency has changed. 96 if (last_rtp_clock_frequency_hz_ != rtp_clock_frequency_hz) { 97 return true; 98 } 99 100 // Should if the RTP clock frequency is invalid. 101 if (rtp_clock_frequency_hz <= 0) { 102 return true; 103 } 104 105 // Should if the estimated capture clock offset has changed. 106 if (last_estimated_capture_clock_offset_ != estimated_capture_clock_offset) { 107 return true; 108 } 109 110 // Should if interpolation would introduce too much error. 111 const uint64_t interpolated_absolute_capture_timestamp = 112 AbsoluteCaptureTimeInterpolator::InterpolateAbsoluteCaptureTimestamp( 113 rtp_timestamp, rtp_clock_frequency_hz, last_rtp_timestamp_, 114 uint64_t{last_absolute_capture_time_}); 115 const uint64_t absolute_capture_timestamp = uint64_t{absolute_capture_time}; 116 const int64_t interpolation_error_ms = UQ32x32ToInt64Ms(std::min( 117 interpolated_absolute_capture_timestamp - absolute_capture_timestamp, 118 absolute_capture_timestamp - interpolated_absolute_capture_timestamp)); 119 if (interpolation_error_ms > kInterpolationMaxError.ms()) { 120 return true; 121 } 122 123 return false; 124 } 125 126 } // namespace webrtc