OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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/modules/congestion_controller/transport_feedback_adapter.h" | 11 #include "webrtc/modules/congestion_controller/transport_feedback_adapter.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <limits> | 14 #include <limits> |
15 | 15 |
16 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
| 18 #include "webrtc/base/mod_ops.h" |
18 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" | 19 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
19 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 20 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |
20 #include "webrtc/modules/congestion_controller/delay_based_bwe.h" | 21 #include "webrtc/modules/congestion_controller/delay_based_bwe.h" |
21 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 22 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
22 #include "webrtc/modules/utility/include/process_thread.h" | 23 #include "webrtc/modules/utility/include/process_thread.h" |
23 #include "webrtc/system_wrappers/include/field_trial.h" | 24 #include "webrtc/system_wrappers/include/field_trial.h" |
24 | 25 |
25 namespace webrtc { | 26 namespace webrtc { |
26 | 27 |
27 const int64_t kNoTimestamp = -1; | 28 const int64_t kNoTimestamp = -1; |
28 const int64_t kSendTimeHistoryWindowMs = 60000; | 29 const int64_t kSendTimeHistoryWindowMs = 60000; |
29 const int64_t kBaseTimestampScaleFactor = | 30 const int64_t kBaseTimestampScaleFactor = |
30 rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 8); | 31 rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 8); |
31 const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24); | 32 const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24); |
32 | 33 |
33 class PacketFeedbackComparator { | |
34 public: | |
35 inline bool operator()(const PacketFeedback& lhs, const PacketFeedback& rhs) { | |
36 if (lhs.arrival_time_ms != rhs.arrival_time_ms) | |
37 return lhs.arrival_time_ms < rhs.arrival_time_ms; | |
38 if (lhs.send_time_ms != rhs.send_time_ms) | |
39 return lhs.send_time_ms < rhs.send_time_ms; | |
40 return lhs.sequence_number < rhs.sequence_number; | |
41 } | |
42 }; | |
43 | |
44 TransportFeedbackAdapter::TransportFeedbackAdapter( | 34 TransportFeedbackAdapter::TransportFeedbackAdapter( |
45 RtcEventLog* event_log, | 35 RtcEventLog* event_log, |
46 Clock* clock, | 36 Clock* clock, |
47 BitrateController* bitrate_controller) | 37 BitrateController* bitrate_controller) |
48 : send_side_bwe_with_overhead_( | 38 : send_side_bwe_with_overhead_( |
49 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), | 39 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), |
50 transport_overhead_bytes_per_packet_(0), | 40 transport_overhead_bytes_per_packet_(0), |
51 send_time_history_(clock, kSendTimeHistoryWindowMs), | 41 send_time_history_(clock, kSendTimeHistoryWindowMs), |
52 event_log_(event_log), | 42 event_log_(event_log), |
53 clock_(clock), | 43 clock_(clock), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } else if (std::abs(delta + kBaseTimestampRangeSizeUs) < std::abs(delta)) { | 106 } else if (std::abs(delta + kBaseTimestampRangeSizeUs) < std::abs(delta)) { |
117 delta += kBaseTimestampRangeSizeUs; // Wrap forwards. | 107 delta += kBaseTimestampRangeSizeUs; // Wrap forwards. |
118 } | 108 } |
119 | 109 |
120 current_offset_ms_ += delta / 1000; | 110 current_offset_ms_ += delta / 1000; |
121 } | 111 } |
122 last_timestamp_us_ = timestamp_us; | 112 last_timestamp_us_ = timestamp_us; |
123 | 113 |
124 auto received_packets = feedback.GetReceivedPackets(); | 114 auto received_packets = feedback.GetReceivedPackets(); |
125 std::vector<PacketFeedback> packet_feedback_vector; | 115 std::vector<PacketFeedback> packet_feedback_vector; |
126 packet_feedback_vector.reserve(received_packets.size()); | |
127 if (received_packets.empty()) { | 116 if (received_packets.empty()) { |
128 LOG(LS_INFO) << "Empty transport feedback packet received."; | 117 LOG(LS_INFO) << "Empty transport feedback packet received."; |
129 return packet_feedback_vector; | 118 return packet_feedback_vector; |
130 } | 119 } |
| 120 const uint16_t last_sequence_number = |
| 121 received_packets.back().sequence_number(); |
| 122 const size_t packet_count = |
| 123 1 + ForwardDiff(feedback.GetBaseSequence(), last_sequence_number); |
| 124 packet_feedback_vector.reserve(packet_count); |
| 125 // feedback.GetStatusVector().size() is a less efficient way to reach what |
| 126 // should be the same value. |
| 127 RTC_DCHECK_EQ(packet_count, feedback.GetStatusVector().size()); |
| 128 |
131 { | 129 { |
132 rtc::CritScope cs(&lock_); | 130 rtc::CritScope cs(&lock_); |
133 size_t failed_lookups = 0; | 131 size_t failed_lookups = 0; |
134 int64_t offset_us = 0; | 132 int64_t offset_us = 0; |
135 int64_t timestamp_ms = 0; | 133 int64_t timestamp_ms = 0; |
136 for (const auto& packet : feedback.GetReceivedPackets()) { | 134 uint16_t seq_num = feedback.GetBaseSequence(); |
| 135 for (const auto& packet : received_packets) { |
| 136 // Insert into the vector those unreceived packets which precede this |
| 137 // iteration's received packet. |
| 138 for (; seq_num != packet.sequence_number(); ++seq_num) { |
| 139 PacketFeedback packet_feedback(PacketFeedback::kNotReceived, seq_num); |
| 140 // Note: Element not removed from history because it might be reported |
| 141 // as received by another feedback. |
| 142 if (!send_time_history_.GetFeedback(&packet_feedback, false)) |
| 143 ++failed_lookups; |
| 144 packet_feedback_vector.push_back(packet_feedback); |
| 145 } |
| 146 |
| 147 // Handle this iteration's received packet. |
137 offset_us += packet.delta_us(); | 148 offset_us += packet.delta_us(); |
138 timestamp_ms = current_offset_ms_ + (offset_us / 1000); | 149 timestamp_ms = current_offset_ms_ + (offset_us / 1000); |
139 PacketFeedback packet_feedback(timestamp_ms, packet.sequence_number()); | 150 PacketFeedback packet_feedback(timestamp_ms, packet.sequence_number()); |
140 if (!send_time_history_.GetFeedback(&packet_feedback, true)) | 151 if (!send_time_history_.GetFeedback(&packet_feedback, true)) |
141 ++failed_lookups; | 152 ++failed_lookups; |
142 packet_feedback_vector.push_back(packet_feedback); | 153 packet_feedback_vector.push_back(packet_feedback); |
| 154 |
| 155 ++seq_num; |
143 } | 156 } |
144 std::sort(packet_feedback_vector.begin(), packet_feedback_vector.end(), | 157 |
145 PacketFeedbackComparator()); | |
146 if (failed_lookups > 0) { | 158 if (failed_lookups > 0) { |
147 LOG(LS_WARNING) << "Failed to lookup send time for " << failed_lookups | 159 LOG(LS_WARNING) << "Failed to lookup send time for " << failed_lookups |
148 << " packet" << (failed_lookups > 1 ? "s" : "") | 160 << " packet" << (failed_lookups > 1 ? "s" : "") |
149 << ". Send time history too small?"; | 161 << ". Send time history too small?"; |
150 } | 162 } |
151 } | 163 } |
152 return packet_feedback_vector; | 164 return packet_feedback_vector; |
153 } | 165 } |
154 | 166 |
155 void TransportFeedbackAdapter::OnTransportFeedback( | 167 void TransportFeedbackAdapter::OnTransportFeedback( |
(...skipping 14 matching lines...) Expand all Loading... |
170 return last_packet_feedback_vector_; | 182 return last_packet_feedback_vector_; |
171 } | 183 } |
172 | 184 |
173 void TransportFeedbackAdapter::OnRttUpdate(int64_t avg_rtt_ms, | 185 void TransportFeedbackAdapter::OnRttUpdate(int64_t avg_rtt_ms, |
174 int64_t max_rtt_ms) { | 186 int64_t max_rtt_ms) { |
175 rtc::CritScope cs(&bwe_lock_); | 187 rtc::CritScope cs(&bwe_lock_); |
176 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); | 188 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); |
177 } | 189 } |
178 | 190 |
179 } // namespace webrtc | 191 } // namespace webrtc |
OLD | NEW |