OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/system_wrappers/include/rtp_to_ntp.h" | 11 #include "webrtc/system_wrappers/include/rtp_to_ntp.h" |
12 | 12 |
13 #include "webrtc/base/logging.h" | 13 #include "webrtc/base/logging.h" |
14 #include "webrtc/system_wrappers/include/clock.h" | 14 #include "webrtc/system_wrappers/include/clock.h" |
15 | 15 |
16 namespace webrtc { | 16 namespace webrtc { |
17 namespace { | 17 namespace { |
| 18 // Number of RTCP SR reports to use to map between RTP and NTP. |
| 19 const size_t kNumRtcpReportsToUse = 2; |
| 20 |
18 // Calculates the RTP timestamp frequency from two pairs of NTP/RTP timestamps. | 21 // Calculates the RTP timestamp frequency from two pairs of NTP/RTP timestamps. |
19 bool CalculateFrequency(int64_t rtcp_ntp_ms1, | 22 bool CalculateFrequency(int64_t rtcp_ntp_ms1, |
20 uint32_t rtp_timestamp1, | 23 uint32_t rtp_timestamp1, |
21 int64_t rtcp_ntp_ms2, | 24 int64_t rtcp_ntp_ms2, |
22 uint32_t rtp_timestamp2, | 25 uint32_t rtp_timestamp2, |
23 double* frequency_khz) { | 26 double* frequency_khz) { |
24 if (rtcp_ntp_ms1 <= rtcp_ntp_ms2) { | 27 if (rtcp_ntp_ms1 <= rtcp_ntp_ms2) { |
25 return false; | 28 return false; |
26 } | 29 } |
27 *frequency_khz = static_cast<double>(rtp_timestamp1 - rtp_timestamp2) / | 30 *frequency_khz = static_cast<double>(rtp_timestamp1 - rtp_timestamp2) / |
(...skipping 10 matching lines...) Expand all Loading... |
38 if (wraps < 0) { | 41 if (wraps < 0) { |
39 // Reordering, don't use this packet. | 42 // Reordering, don't use this packet. |
40 return false; | 43 return false; |
41 } | 44 } |
42 *compensated_timestamp = new_timestamp + (wraps << 32); | 45 *compensated_timestamp = new_timestamp + (wraps << 32); |
43 return true; | 46 return true; |
44 } | 47 } |
45 } // namespace | 48 } // namespace |
46 | 49 |
47 // Class holding RTP and NTP timestamp from a RTCP SR report. | 50 // Class holding RTP and NTP timestamp from a RTCP SR report. |
48 RtcpMeasurement::RtcpMeasurement() | 51 RtcpMeasurement::RtcpMeasurement() : ntp_time(0, 0), rtp_timestamp(0) {} |
49 : ntp_secs(0), ntp_frac(0), rtp_timestamp(0) {} | |
50 | 52 |
51 RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs, | 53 RtcpMeasurement::RtcpMeasurement(uint32_t ntp_secs, |
52 uint32_t ntp_frac, | 54 uint32_t ntp_frac, |
53 uint32_t timestamp) | 55 uint32_t timestamp) |
54 : ntp_secs(ntp_secs), ntp_frac(ntp_frac), rtp_timestamp(timestamp) {} | 56 : ntp_time(ntp_secs, ntp_frac), rtp_timestamp(timestamp) {} |
55 | 57 |
56 bool RtcpMeasurement::IsEqual(const RtcpMeasurement& other) const { | 58 bool RtcpMeasurement::IsEqual(const RtcpMeasurement& other) const { |
57 // Use || since two equal timestamps will result in zero frequency and in | 59 // Use || since two equal timestamps will result in zero frequency and in |
58 // RtpToNtpMs, |rtp_timestamp_ms| is estimated by dividing by the frequency. | 60 // RtpToNtpMs, |rtp_timestamp_ms| is estimated by dividing by the frequency. |
59 return (ntp_secs == other.ntp_secs && ntp_frac == other.ntp_frac) || | 61 return (ntp_time == other.ntp_time) || (rtp_timestamp == other.rtp_timestamp); |
60 (rtp_timestamp == other.rtp_timestamp); | |
61 } | 62 } |
62 | 63 |
63 // Class holding list of RTP and NTP timestamp pairs. | 64 // Class holding list of RTP and NTP timestamp pairs. |
64 RtcpMeasurements::RtcpMeasurements() {} | 65 RtcpMeasurements::RtcpMeasurements() {} |
65 RtcpMeasurements::~RtcpMeasurements() {} | 66 RtcpMeasurements::~RtcpMeasurements() {} |
66 | 67 |
67 bool RtcpMeasurements::Contains(const RtcpMeasurement& other) const { | 68 bool RtcpMeasurements::Contains(const RtcpMeasurement& other) const { |
68 for (const auto& it : list) { | 69 for (const auto& it : list) { |
69 if (it.IsEqual(other)) | 70 if (it.IsEqual(other)) |
70 return true; | 71 return true; |
71 } | 72 } |
72 return false; | 73 return false; |
73 } | 74 } |
74 | 75 |
75 bool RtcpMeasurements::IsValid(const RtcpMeasurement& other) const { | 76 bool RtcpMeasurements::IsValid(const RtcpMeasurement& other) const { |
76 if (other.ntp_secs == 0 && other.ntp_frac == 0) { | 77 if (!other.ntp_time.Valid()) |
77 // Invalid or not defined. | |
78 return false; | 78 return false; |
79 } | 79 |
80 int64_t ntp_ms_new = Clock::NtpToMs(other.ntp_secs, other.ntp_frac); | 80 int64_t ntp_ms_new = other.ntp_time.ToMs(); |
81 for (const auto& it : list) { | 81 for (const auto& it : list) { |
82 if (ntp_ms_new <= Clock::NtpToMs(it.ntp_secs, it.ntp_frac)) { | 82 if (ntp_ms_new <= it.ntp_time.ToMs()) { |
83 // Old report. | 83 // Old report. |
84 return false; | 84 return false; |
85 } | 85 } |
86 int64_t timestamp_new = other.rtp_timestamp; | 86 int64_t timestamp_new = other.rtp_timestamp; |
87 if (!CompensateForWrapAround(timestamp_new, it.rtp_timestamp, | 87 if (!CompensateForWrapAround(timestamp_new, it.rtp_timestamp, |
88 ×tamp_new)) { | 88 ×tamp_new)) { |
89 return false; | 89 return false; |
90 } | 90 } |
91 if (timestamp_new <= it.rtp_timestamp) { | 91 if (timestamp_new <= it.rtp_timestamp) { |
92 LOG(LS_WARNING) << "Newer RTCP SR report with older RTP timestamp."; | 92 LOG(LS_WARNING) << "Newer RTCP SR report with older RTP timestamp."; |
93 return false; | 93 return false; |
94 } | 94 } |
95 } | 95 } |
96 return true; | 96 return true; |
97 } | 97 } |
98 | 98 |
99 void RtcpMeasurements::UpdateParameters() { | 99 void RtcpMeasurements::UpdateParameters() { |
100 if (list.size() != 2) | 100 if (list.size() != kNumRtcpReportsToUse) |
101 return; | 101 return; |
102 | 102 |
103 int64_t timestamp_new = list.front().rtp_timestamp; | 103 int64_t timestamp_new = list.front().rtp_timestamp; |
104 int64_t timestamp_old = list.back().rtp_timestamp; | 104 int64_t timestamp_old = list.back().rtp_timestamp; |
105 if (!CompensateForWrapAround(timestamp_new, timestamp_old, ×tamp_new)) | 105 if (!CompensateForWrapAround(timestamp_new, timestamp_old, ×tamp_new)) |
106 return; | 106 return; |
107 | 107 |
108 int64_t ntp_ms_new = | 108 int64_t ntp_ms_new = list.front().ntp_time.ToMs(); |
109 Clock::NtpToMs(list.front().ntp_secs, list.front().ntp_frac); | 109 int64_t ntp_ms_old = list.back().ntp_time.ToMs(); |
110 int64_t ntp_ms_old = | |
111 Clock::NtpToMs(list.back().ntp_secs, list.back().ntp_frac); | |
112 | 110 |
113 if (!CalculateFrequency(ntp_ms_new, timestamp_new, ntp_ms_old, timestamp_old, | 111 if (!CalculateFrequency(ntp_ms_new, timestamp_new, ntp_ms_old, timestamp_old, |
114 ¶ms.frequency_khz)) { | 112 ¶ms.frequency_khz)) { |
115 return; | 113 return; |
116 } | 114 } |
117 params.offset_ms = timestamp_new - params.frequency_khz * ntp_ms_new; | 115 params.offset_ms = timestamp_new - params.frequency_khz * ntp_ms_new; |
118 params.calculated = true; | 116 params.calculated = true; |
119 } | 117 } |
120 | 118 |
121 // Updates list holding NTP and RTP timestamp pairs. | 119 // Updates list holding NTP and RTP timestamp pairs. |
122 bool UpdateRtcpList(uint32_t ntp_secs, | 120 bool UpdateRtcpList(uint32_t ntp_secs, |
123 uint32_t ntp_frac, | 121 uint32_t ntp_frac, |
124 uint32_t rtp_timestamp, | 122 uint32_t rtp_timestamp, |
125 RtcpMeasurements* rtcp_measurements, | 123 RtcpMeasurements* rtcp_measurements, |
126 bool* new_rtcp_sr) { | 124 bool* new_rtcp_sr) { |
127 *new_rtcp_sr = false; | 125 *new_rtcp_sr = false; |
128 | 126 |
129 RtcpMeasurement measurement(ntp_secs, ntp_frac, rtp_timestamp); | 127 RtcpMeasurement measurement(ntp_secs, ntp_frac, rtp_timestamp); |
130 if (rtcp_measurements->Contains(measurement)) { | 128 if (rtcp_measurements->Contains(measurement)) { |
131 // RTCP SR report already added. | 129 // RTCP SR report already added. |
132 return true; | 130 return true; |
133 } | 131 } |
134 | 132 |
135 if (!rtcp_measurements->IsValid(measurement)) { | 133 if (!rtcp_measurements->IsValid(measurement)) { |
136 // Old report or invalid parameters. | 134 // Old report or invalid parameters. |
137 return false; | 135 return false; |
138 } | 136 } |
139 | 137 |
140 // Two RTCP SR reports are needed to map between RTP and NTP. | 138 // Insert new RTCP SR report. |
141 // More than two will not improve the mapping. | 139 if (rtcp_measurements->list.size() == kNumRtcpReportsToUse) |
142 if (rtcp_measurements->list.size() == 2) | |
143 rtcp_measurements->list.pop_back(); | 140 rtcp_measurements->list.pop_back(); |
144 | 141 |
145 rtcp_measurements->list.push_front(measurement); | 142 rtcp_measurements->list.push_front(measurement); |
146 *new_rtcp_sr = true; | 143 *new_rtcp_sr = true; |
147 | 144 |
148 // List updated, calculate new parameters. | 145 // List updated, calculate new parameters. |
149 rtcp_measurements->UpdateParameters(); | 146 rtcp_measurements->UpdateParameters(); |
150 return true; | 147 return true; |
151 } | 148 } |
152 | 149 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 } | 186 } |
190 } else if (static_cast<int32_t>(old_timestamp - new_timestamp) > 0) { | 187 } else if (static_cast<int32_t>(old_timestamp - new_timestamp) > 0) { |
191 // This difference should be less than -2^31 if we have had a backward wrap | 188 // This difference should be less than -2^31 if we have had a backward wrap |
192 // around. Since it is cast to a int32_t, it should be positive. | 189 // around. Since it is cast to a int32_t, it should be positive. |
193 return -1; | 190 return -1; |
194 } | 191 } |
195 return 0; | 192 return 0; |
196 } | 193 } |
197 | 194 |
198 } // namespace webrtc | 195 } // namespace webrtc |
OLD | NEW |