Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h" | 11 #include "webrtc/modules/congestion_controller/delay_based_bitrate_probing.h" |
| 12 | 12 |
| 13 #include <math.h> | 13 #include <math.h> |
| 14 | 14 |
| 15 #include <algorithm> | 15 #include <algorithm> |
| 16 | 16 |
| 17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/constructormagic.h" | 18 #include "webrtc/base/constructormagic.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/thread_annotations.h" | 20 #include "webrtc/base/thread_annotations.h" |
| 21 #include "webrtc/modules/pacing/paced_sender.h" | 21 #include "webrtc/modules/pacing/paced_sender.h" |
| 22 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" | 22 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" |
| 23 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 23 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
| 24 #include "webrtc/typedefs.h" | 24 #include "webrtc/typedefs.h" |
| 25 | 25 |
| 26 namespace webrtc { | 26 namespace { |
| 27 | |
| 28 enum { | 27 enum { |
| 29 kTimestampGroupLengthMs = 5, | 28 kTimestampGroupLengthMs = 5, |
| 30 kAbsSendTimeFraction = 18, | 29 kAbsSendTimeFraction = 18, |
| 31 kAbsSendTimeInterArrivalUpshift = 8, | 30 kAbsSendTimeInterArrivalUpshift = 8, |
| 32 kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift, | 31 kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift, |
| 33 kInitialProbingIntervalMs = 2000, | 32 kInitialProbingIntervalMs = 2000, |
| 34 kMinClusterSize = 4, | 33 kMinClusterSize = 4, |
| 35 kMaxProbePackets = 15, | 34 kMaxProbePackets = 15, |
| 36 kExpectedNumberOfProbes = 3 | 35 kExpectedNumberOfProbes = 3 |
| 37 }; | 36 }; |
| 38 | 37 |
| 39 static const double kTimestampToMs = 1000.0 / | |
| 40 static_cast<double>(1 << kInterArrivalShift); | |
| 41 | |
| 42 template<typename K, typename V> | |
| 43 std::vector<K> Keys(const std::map<K, V>& map) { | |
| 44 std::vector<K> keys; | |
| 45 keys.reserve(map.size()); | |
| 46 for (typename std::map<K, V>::const_iterator it = map.begin(); | |
| 47 it != map.end(); ++it) { | |
| 48 keys.push_back(it->first); | |
| 49 } | |
| 50 return keys; | |
| 51 } | |
| 52 | |
| 53 uint32_t ConvertMsTo24Bits(int64_t time_ms) { | 38 uint32_t ConvertMsTo24Bits(int64_t time_ms) { |
| 54 uint32_t time_24_bits = | 39 uint32_t time_24_bits = |
| 55 static_cast<uint32_t>( | 40 static_cast<uint32_t>( |
| 56 ((static_cast<uint64_t>(time_ms) << kAbsSendTimeFraction) + 500) / | 41 ((static_cast<uint64_t>(time_ms) << kAbsSendTimeFraction) + 500) / |
| 57 1000) & | 42 1000) & |
| 58 0x00FFFFFF; | 43 0x00FFFFFF; |
| 59 return time_24_bits; | 44 return time_24_bits; |
| 60 } | 45 } |
| 46 } // namespace | |
| 61 | 47 |
| 62 bool RemoteBitrateEstimatorAbsSendTime::IsWithinClusterBounds( | 48 namespace webrtc { |
|
danilchap
2016/06/03 14:11:45
Why keep this constant and function in webrtc inst
philipel
2016/06/03 14:54:55
Wanted to do as few changes as possible, but I gue
| |
| 63 int send_delta_ms, | 49 |
| 64 const Cluster& cluster_aggregate) { | 50 static const double kTimestampToMs = |
| 65 if (cluster_aggregate.count == 0) | 51 1000.0 / static_cast<double>(1 << kInterArrivalShift); |
| 66 return true; | 52 |
| 67 float cluster_mean = cluster_aggregate.send_mean_ms / | 53 template <typename K, typename V> |
| 68 static_cast<float>(cluster_aggregate.count); | 54 std::vector<K> Keys(const std::map<K, V>& map) { |
| 69 return fabs(static_cast<float>(send_delta_ms) - cluster_mean) < 2.5f; | 55 std::vector<K> keys; |
| 56 keys.reserve(map.size()); | |
| 57 for (typename std::map<K, V>::const_iterator it = map.begin(); | |
| 58 it != map.end(); ++it) { | |
| 59 keys.push_back(it->first); | |
| 70 } | 60 } |
| 71 | 61 return keys; |
| 72 void RemoteBitrateEstimatorAbsSendTime::AddCluster( | |
| 73 std::list<Cluster>* clusters, | |
| 74 Cluster* cluster) { | |
| 75 cluster->send_mean_ms /= static_cast<float>(cluster->count); | |
| 76 cluster->recv_mean_ms /= static_cast<float>(cluster->count); | |
| 77 cluster->mean_size /= cluster->count; | |
| 78 clusters->push_back(*cluster); | |
| 79 } | |
| 80 | |
| 81 RemoteBitrateEstimatorAbsSendTime::RemoteBitrateEstimatorAbsSendTime( | |
| 82 RemoteBitrateObserver* observer) | |
| 83 : observer_(observer), | |
| 84 inter_arrival_(), | |
| 85 estimator_(), | |
| 86 detector_(OverUseDetectorOptions()), | |
| 87 incoming_bitrate_(kBitrateWindowMs, 8000), | |
| 88 total_probes_received_(0), | |
| 89 first_packet_time_ms_(-1), | |
| 90 last_update_ms_(-1), | |
| 91 ssrcs_() { | |
| 92 RTC_DCHECK(observer_); | |
| 93 LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating."; | |
| 94 network_thread_.DetachFromThread(); | |
| 95 } | 62 } |
| 96 | 63 |
| 97 void RemoteBitrateEstimatorAbsSendTime::ComputeClusters( | 64 void DelayBasedProbingEstimator::AddCluster(std::list<Cluster>* clusters, |
| 65 Cluster* cluster) { | |
| 66 cluster->send_mean_ms /= static_cast<float>(cluster->count); | |
| 67 cluster->recv_mean_ms /= static_cast<float>(cluster->count); | |
| 68 cluster->mean_size /= cluster->count; | |
| 69 clusters->push_back(*cluster); | |
| 70 } | |
| 71 | |
| 72 DelayBasedProbingEstimator::DelayBasedProbingEstimator( | |
| 73 RemoteBitrateObserver* observer) | |
| 74 : observer_(observer), | |
| 75 inter_arrival_(), | |
| 76 estimator_(), | |
| 77 detector_(OverUseDetectorOptions()), | |
| 78 incoming_bitrate_(kBitrateWindowMs, 8000), | |
| 79 total_probes_received_(0), | |
| 80 first_packet_time_ms_(-1), | |
| 81 last_update_ms_(-1), | |
| 82 ssrcs_() { | |
| 83 RTC_DCHECK(observer_); | |
| 84 // XXX(philipel): The BitrateEstimatorTest relies on this EXACT log line. | |
|
danilchap
2016/06/03 14:11:45
XXX=TODO? ( fix the test)
stefan-webrtc
2016/06/03 14:30:40
The test is only useful for the receive-side BWE,
philipel
2016/06/03 14:54:55
XXX = dirty code. I think it is best to not change
stefan-webrtc
2016/06/08 08:57:09
I think that the particular test that relies on th
| |
| 85 LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating."; | |
| 86 network_thread_.DetachFromThread(); | |
| 87 } | |
| 88 | |
| 89 void DelayBasedProbingEstimator::ComputeClusters( | |
| 98 std::list<Cluster>* clusters) const { | 90 std::list<Cluster>* clusters) const { |
| 99 Cluster current; | 91 Cluster current; |
| 100 int64_t prev_send_time = -1; | 92 int64_t prev_send_time = -1; |
| 101 int64_t prev_recv_time = -1; | 93 int64_t prev_recv_time = -1; |
| 94 int last_probe_cluster_id = -1; | |
| 102 for (std::list<Probe>::const_iterator it = probes_.begin(); | 95 for (std::list<Probe>::const_iterator it = probes_.begin(); |
| 103 it != probes_.end(); | 96 it != probes_.end(); ++it) { |
| 104 ++it) { | 97 if (last_probe_cluster_id == -1) |
| 98 last_probe_cluster_id = it->probe_cluster_id; | |
| 105 if (prev_send_time >= 0) { | 99 if (prev_send_time >= 0) { |
| 106 int send_delta_ms = it->send_time_ms - prev_send_time; | 100 int send_delta_ms = it->send_time_ms - prev_send_time; |
| 107 int recv_delta_ms = it->recv_time_ms - prev_recv_time; | 101 int recv_delta_ms = it->recv_time_ms - prev_recv_time; |
| 108 if (send_delta_ms >= 1 && recv_delta_ms >= 1) { | 102 if (send_delta_ms >= 1 && recv_delta_ms >= 1) { |
| 109 ++current.num_above_min_delta; | 103 ++current.num_above_min_delta; |
| 110 } | 104 } |
| 111 if (!IsWithinClusterBounds(send_delta_ms, current)) { | 105 if (it->probe_cluster_id == last_probe_cluster_id) { |
|
stefan-webrtc
2016/06/03 13:46:23
Could you perhaps introduce these changes in a sep
philipel
2016/06/03 14:54:55
Not 100% sure what you mean. This logic must be ch
stefan-webrtc
2016/06/08 08:57:09
What I meant was that you could make a separate CL
| |
| 112 if (current.count >= kMinClusterSize) | 106 if (current.count >= kMinClusterSize) |
| 113 AddCluster(clusters, ¤t); | 107 AddCluster(clusters, ¤t); |
| 114 current = Cluster(); | 108 current = Cluster(); |
| 115 } | 109 } |
| 116 current.send_mean_ms += send_delta_ms; | 110 current.send_mean_ms += send_delta_ms; |
| 117 current.recv_mean_ms += recv_delta_ms; | 111 current.recv_mean_ms += recv_delta_ms; |
| 118 current.mean_size += it->payload_size; | 112 current.mean_size += it->payload_size; |
| 119 ++current.count; | 113 ++current.count; |
| 120 } | 114 } |
| 121 prev_send_time = it->send_time_ms; | 115 prev_send_time = it->send_time_ms; |
| 122 prev_recv_time = it->recv_time_ms; | 116 prev_recv_time = it->recv_time_ms; |
| 123 } | 117 } |
| 124 if (current.count >= kMinClusterSize) | 118 if (current.count >= kMinClusterSize) |
| 125 AddCluster(clusters, ¤t); | 119 AddCluster(clusters, ¤t); |
| 126 } | 120 } |
| 127 | 121 |
| 128 std::list<Cluster>::const_iterator | 122 std::list<Cluster>::const_iterator DelayBasedProbingEstimator::FindBestProbe( |
| 129 RemoteBitrateEstimatorAbsSendTime::FindBestProbe( | |
| 130 const std::list<Cluster>& clusters) const { | 123 const std::list<Cluster>& clusters) const { |
| 131 int highest_probe_bitrate_bps = 0; | 124 int highest_probe_bitrate_bps = 0; |
| 132 std::list<Cluster>::const_iterator best_it = clusters.end(); | 125 std::list<Cluster>::const_iterator best_it = clusters.end(); |
| 133 for (std::list<Cluster>::const_iterator it = clusters.begin(); | 126 for (std::list<Cluster>::const_iterator it = clusters.begin(); |
| 134 it != clusters.end(); | 127 it != clusters.end(); ++it) { |
| 135 ++it) { | |
| 136 if (it->send_mean_ms == 0 || it->recv_mean_ms == 0) | 128 if (it->send_mean_ms == 0 || it->recv_mean_ms == 0) |
| 137 continue; | 129 continue; |
| 138 int send_bitrate_bps = it->mean_size * 8 * 1000 / it->send_mean_ms; | 130 int send_bitrate_bps = it->mean_size * 8 * 1000 / it->send_mean_ms; |
| 139 int recv_bitrate_bps = it->mean_size * 8 * 1000 / it->recv_mean_ms; | 131 int recv_bitrate_bps = it->mean_size * 8 * 1000 / it->recv_mean_ms; |
| 140 if (it->num_above_min_delta > it->count / 2 && | 132 if (it->num_above_min_delta > it->count / 2 && |
| 141 (it->recv_mean_ms - it->send_mean_ms <= 2.0f && | 133 (it->recv_mean_ms - it->send_mean_ms <= 2.0f && |
| 142 it->send_mean_ms - it->recv_mean_ms <= 5.0f)) { | 134 it->send_mean_ms - it->recv_mean_ms <= 5.0f)) { |
| 143 int probe_bitrate_bps = | 135 int probe_bitrate_bps = |
| 144 std::min(it->GetSendBitrateBps(), it->GetRecvBitrateBps()); | 136 std::min(it->GetSendBitrateBps(), it->GetRecvBitrateBps()); |
| 145 if (probe_bitrate_bps > highest_probe_bitrate_bps) { | 137 if (probe_bitrate_bps > highest_probe_bitrate_bps) { |
| 146 highest_probe_bitrate_bps = probe_bitrate_bps; | 138 highest_probe_bitrate_bps = probe_bitrate_bps; |
| 147 best_it = it; | 139 best_it = it; |
| 148 } | 140 } |
| 149 } else { | 141 } else { |
| 150 LOG(LS_INFO) << "Probe failed, sent at " << send_bitrate_bps | 142 LOG(LS_INFO) << "Probe failed, sent at " << send_bitrate_bps |
| 151 << " bps, received at " << recv_bitrate_bps | 143 << " bps, received at " << recv_bitrate_bps |
| 152 << " bps. Mean send delta: " << it->send_mean_ms | 144 << " bps. Mean send delta: " << it->send_mean_ms |
| 153 << " ms, mean recv delta: " << it->recv_mean_ms | 145 << " ms, mean recv delta: " << it->recv_mean_ms |
| 154 << " ms, num probes: " << it->count; | 146 << " ms, num probes: " << it->count; |
| 155 break; | 147 break; |
| 156 } | 148 } |
| 157 } | 149 } |
| 158 return best_it; | 150 return best_it; |
| 159 } | 151 } |
| 160 | 152 |
| 161 RemoteBitrateEstimatorAbsSendTime::ProbeResult | 153 DelayBasedProbingEstimator::ProbeResult |
| 162 RemoteBitrateEstimatorAbsSendTime::ProcessClusters(int64_t now_ms) { | 154 DelayBasedProbingEstimator::ProcessClusters(int64_t now_ms) { |
| 163 std::list<Cluster> clusters; | 155 std::list<Cluster> clusters; |
| 164 ComputeClusters(&clusters); | 156 ComputeClusters(&clusters); |
| 165 if (clusters.empty()) { | 157 if (clusters.empty()) { |
| 166 // If we reach the max number of probe packets and still have no clusters, | 158 // If we reach the max number of probe packets and still have no clusters, |
| 167 // we will remove the oldest one. | 159 // we will remove the oldest one. |
| 168 if (probes_.size() >= kMaxProbePackets) | 160 if (probes_.size() >= kMaxProbePackets) |
| 169 probes_.pop_front(); | 161 probes_.pop_front(); |
| 170 return ProbeResult::kNoUpdate; | 162 return ProbeResult::kNoUpdate; |
| 171 } | 163 } |
| 172 | 164 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 188 } | 180 } |
| 189 } | 181 } |
| 190 | 182 |
| 191 // Not probing and received non-probe packet, or finished with current set | 183 // Not probing and received non-probe packet, or finished with current set |
| 192 // of probes. | 184 // of probes. |
| 193 if (clusters.size() >= kExpectedNumberOfProbes) | 185 if (clusters.size() >= kExpectedNumberOfProbes) |
| 194 probes_.clear(); | 186 probes_.clear(); |
| 195 return ProbeResult::kNoUpdate; | 187 return ProbeResult::kNoUpdate; |
| 196 } | 188 } |
| 197 | 189 |
| 198 bool RemoteBitrateEstimatorAbsSendTime::IsBitrateImproving( | 190 bool DelayBasedProbingEstimator::IsBitrateImproving(int new_bitrate_bps) const { |
| 199 int new_bitrate_bps) const { | |
| 200 bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0; | 191 bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0; |
| 201 bool bitrate_above_estimate = | 192 bool bitrate_above_estimate = |
| 202 remote_rate_.ValidEstimate() && | 193 remote_rate_.ValidEstimate() && |
| 203 new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate()); | 194 new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate()); |
| 204 return initial_probe || bitrate_above_estimate; | 195 return initial_probe || bitrate_above_estimate; |
| 205 } | 196 } |
| 206 | 197 |
| 207 void RemoteBitrateEstimatorAbsSendTime::IncomingPacketFeedbackVector( | 198 void DelayBasedProbingEstimator::IncomingPacketFeedbackVector( |
| 208 const std::vector<PacketInfo>& packet_feedback_vector) { | 199 const std::vector<PacketInfo>& packet_feedback_vector) { |
| 209 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 200 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
| 210 for (const auto& packet_info : packet_feedback_vector) { | 201 for (const auto& packet_info : packet_feedback_vector) { |
| 211 IncomingPacketInfo(packet_info.arrival_time_ms, | 202 IncomingPacketInfo(packet_info.arrival_time_ms, |
| 212 ConvertMsTo24Bits(packet_info.send_time_ms), | 203 ConvertMsTo24Bits(packet_info.send_time_ms), |
| 213 packet_info.payload_size, 0, packet_info.was_paced); | 204 packet_info.payload_size, 0, packet_info.was_paced, |
| 205 packet_info.probe_cluster_id); | |
| 214 } | 206 } |
| 215 } | 207 } |
| 216 | 208 |
| 217 void RemoteBitrateEstimatorAbsSendTime::IncomingPacket(int64_t arrival_time_ms, | 209 void DelayBasedProbingEstimator::IncomingPacket(int64_t arrival_time_ms, |
| 218 size_t payload_size, | 210 size_t payload_size, |
| 219 const RTPHeader& header, | 211 const RTPHeader& header, |
| 220 bool was_paced) { | 212 bool was_paced) { |
| 221 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 213 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
| 222 if (!header.extension.hasAbsoluteSendTime) { | 214 if (!header.extension.hasAbsoluteSendTime) { |
| 223 LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTimeImpl: Incoming packet " | 215 // XXX(philipel): The BitrateEstimatorTest relies on this EXACT log line. |
|
danilchap
2016/06/03 14:11:45
ditto
philipel
2016/06/03 14:54:55
Acknowledged.
| |
| 216 LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTime: Incoming packet " | |
| 224 "is missing absolute send time extension!"; | 217 "is missing absolute send time extension!"; |
| 225 return; | 218 return; |
| 226 } | 219 } |
| 227 IncomingPacketInfo(arrival_time_ms, header.extension.absoluteSendTime, | 220 IncomingPacketInfo(arrival_time_ms, header.extension.absoluteSendTime, |
| 228 payload_size, header.ssrc, was_paced); | 221 payload_size, header.ssrc, was_paced, |
| 222 PacketInfo::kNotAProbe); | |
| 229 } | 223 } |
| 230 | 224 |
| 231 void RemoteBitrateEstimatorAbsSendTime::IncomingPacketInfo( | 225 void DelayBasedProbingEstimator::IncomingPacketInfo(int64_t arrival_time_ms, |
| 232 int64_t arrival_time_ms, | 226 uint32_t send_time_24bits, |
| 233 uint32_t send_time_24bits, | 227 size_t payload_size, |
| 234 size_t payload_size, | 228 uint32_t ssrc, |
| 235 uint32_t ssrc, | 229 bool was_paced, |
| 236 bool was_paced) { | 230 int probe_cluster_id) { |
| 237 assert(send_time_24bits < (1ul << 24)); | 231 assert(send_time_24bits < (1ul << 24)); |
| 238 // Shift up send time to use the full 32 bits that inter_arrival works with, | 232 // Shift up send time to use the full 32 bits that inter_arrival works with, |
| 239 // so wrapping works properly. | 233 // so wrapping works properly. |
| 240 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; | 234 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; |
| 241 int64_t send_time_ms = static_cast<int64_t>(timestamp) * kTimestampToMs; | 235 int64_t send_time_ms = static_cast<int64_t>(timestamp) * kTimestampToMs; |
| 242 | 236 |
| 243 int64_t now_ms = arrival_time_ms; | 237 int64_t now_ms = arrival_time_ms; |
| 244 // TODO(holmer): SSRCs are only needed for REMB, should be broken out from | 238 // TODO(holmer): SSRCs are only needed for REMB, should be broken out from |
| 245 // here. | 239 // here. |
| 246 incoming_bitrate_.Update(payload_size, now_ms); | 240 incoming_bitrate_.Update(payload_size, now_ms); |
| 247 | 241 |
| 248 if (first_packet_time_ms_ == -1) | 242 if (first_packet_time_ms_ == -1) |
| 249 first_packet_time_ms_ = arrival_time_ms; | 243 first_packet_time_ms_ = arrival_time_ms; |
| 250 | 244 |
| 251 uint32_t ts_delta = 0; | 245 uint32_t ts_delta = 0; |
| 252 int64_t t_delta = 0; | 246 int64_t t_delta = 0; |
| 253 int size_delta = 0; | 247 int size_delta = 0; |
| 254 // For now only try to detect probes while we don't have a valid estimate, and | 248 |
| 255 // make sure the packet was paced. We currently assume that only packets | |
| 256 // larger than 200 bytes are paced by the sender. | |
| 257 was_paced = was_paced && payload_size > PacedSender::kMinProbePacketSize; | |
| 258 bool update_estimate = false; | 249 bool update_estimate = false; |
| 259 uint32_t target_bitrate_bps = 0; | 250 uint32_t target_bitrate_bps = 0; |
| 260 std::vector<uint32_t> ssrcs; | 251 std::vector<uint32_t> ssrcs; |
| 261 { | 252 { |
| 262 rtc::CritScope lock(&crit_); | 253 rtc::CritScope lock(&crit_); |
| 263 | 254 |
| 264 TimeoutStreams(now_ms); | 255 TimeoutStreams(now_ms); |
| 265 RTC_DCHECK(inter_arrival_.get()); | 256 RTC_DCHECK(inter_arrival_.get()); |
| 266 RTC_DCHECK(estimator_.get()); | 257 RTC_DCHECK(estimator_.get()); |
| 267 ssrcs_[ssrc] = now_ms; | 258 ssrcs_[ssrc] = now_ms; |
| 268 | 259 |
| 269 if (was_paced && | 260 if (probe_cluster_id != PacketInfo::kNotAProbe && |
| 261 payload_size > PacedSender::kMinProbePacketSize && | |
| 270 (!remote_rate_.ValidEstimate() || | 262 (!remote_rate_.ValidEstimate() || |
| 271 now_ms - first_packet_time_ms_ < kInitialProbingIntervalMs)) { | 263 now_ms - first_packet_time_ms_ < kInitialProbingIntervalMs)) { |
| 272 // TODO(holmer): Use a map instead to get correct order? | 264 // TODO(holmer): Use a map instead to get correct order? |
| 273 if (total_probes_received_ < kMaxProbePackets) { | 265 if (total_probes_received_ < kMaxProbePackets) { |
| 274 int send_delta_ms = -1; | 266 int send_delta_ms = -1; |
| 275 int recv_delta_ms = -1; | 267 int recv_delta_ms = -1; |
| 276 if (!probes_.empty()) { | 268 if (!probes_.empty()) { |
| 277 send_delta_ms = send_time_ms - probes_.back().send_time_ms; | 269 send_delta_ms = send_time_ms - probes_.back().send_time_ms; |
| 278 recv_delta_ms = arrival_time_ms - probes_.back().recv_time_ms; | 270 recv_delta_ms = arrival_time_ms - probes_.back().recv_time_ms; |
| 279 } | 271 } |
| 280 LOG(LS_INFO) << "Probe packet received: send time=" << send_time_ms | 272 LOG(LS_INFO) << "Probe packet received: send time=" << send_time_ms |
| 281 << " ms, recv time=" << arrival_time_ms | 273 << " ms, recv time=" << arrival_time_ms |
| 282 << " ms, send delta=" << send_delta_ms | 274 << " ms, send delta=" << send_delta_ms |
| 283 << " ms, recv delta=" << recv_delta_ms << " ms."; | 275 << " ms, recv delta=" << recv_delta_ms << " ms."; |
| 284 } | 276 } |
| 285 probes_.push_back(Probe(send_time_ms, arrival_time_ms, payload_size)); | 277 probes_.push_back( |
| 278 Probe(send_time_ms, arrival_time_ms, payload_size, probe_cluster_id)); | |
| 286 ++total_probes_received_; | 279 ++total_probes_received_; |
| 287 // Make sure that a probe which updated the bitrate immediately has an | 280 // Make sure that a probe which updated the bitrate immediately has an |
| 288 // effect by calling the OnReceiveBitrateChanged callback. | 281 // effect by calling the OnReceiveBitrateChanged callback. |
| 289 if (ProcessClusters(now_ms) == ProbeResult::kBitrateUpdated) | 282 if (ProcessClusters(now_ms) == ProbeResult::kBitrateUpdated) |
| 290 update_estimate = true; | 283 update_estimate = true; |
| 291 } | 284 } |
| 292 if (inter_arrival_->ComputeDeltas(timestamp, arrival_time_ms, payload_size, | 285 if (inter_arrival_->ComputeDeltas(timestamp, arrival_time_ms, payload_size, |
| 293 &ts_delta, &t_delta, &size_delta)) { | 286 &ts_delta, &t_delta, &size_delta)) { |
| 294 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); | 287 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); |
| 295 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State()); | 288 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 322 update_estimate = remote_rate_.ValidEstimate(); | 315 update_estimate = remote_rate_.ValidEstimate(); |
| 323 ssrcs = Keys(ssrcs_); | 316 ssrcs = Keys(ssrcs_); |
| 324 } | 317 } |
| 325 } | 318 } |
| 326 if (update_estimate) { | 319 if (update_estimate) { |
| 327 last_update_ms_ = now_ms; | 320 last_update_ms_ = now_ms; |
| 328 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate_bps); | 321 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate_bps); |
| 329 } | 322 } |
| 330 } | 323 } |
| 331 | 324 |
| 332 void RemoteBitrateEstimatorAbsSendTime::Process() {} | 325 void DelayBasedProbingEstimator::Process() {} |
| 333 | 326 |
| 334 int64_t RemoteBitrateEstimatorAbsSendTime::TimeUntilNextProcess() { | 327 int64_t DelayBasedProbingEstimator::TimeUntilNextProcess() { |
| 335 const int64_t kDisabledModuleTime = 1000; | 328 const int64_t kDisabledModuleTime = 1000; |
| 336 return kDisabledModuleTime; | 329 return kDisabledModuleTime; |
| 337 } | 330 } |
| 338 | 331 |
| 339 void RemoteBitrateEstimatorAbsSendTime::TimeoutStreams(int64_t now_ms) { | 332 void DelayBasedProbingEstimator::TimeoutStreams(int64_t now_ms) { |
| 340 for (Ssrcs::iterator it = ssrcs_.begin(); it != ssrcs_.end();) { | 333 for (Ssrcs::iterator it = ssrcs_.begin(); it != ssrcs_.end();) { |
| 341 if ((now_ms - it->second) > kStreamTimeOutMs) { | 334 if ((now_ms - it->second) > kStreamTimeOutMs) { |
| 342 ssrcs_.erase(it++); | 335 ssrcs_.erase(it++); |
| 343 } else { | 336 } else { |
| 344 ++it; | 337 ++it; |
| 345 } | 338 } |
| 346 } | 339 } |
| 347 if (ssrcs_.empty()) { | 340 if (ssrcs_.empty()) { |
| 348 // We can't update the estimate if we don't have any active streams. | 341 // We can't update the estimate if we don't have any active streams. |
| 349 inter_arrival_.reset( | 342 inter_arrival_.reset( |
| 350 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, | 343 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, |
| 351 kTimestampToMs, true)); | 344 kTimestampToMs, true)); |
| 352 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); | 345 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); |
| 353 // We deliberately don't reset the first_packet_time_ms_ here for now since | 346 // We deliberately don't reset the first_packet_time_ms_ here for now since |
| 354 // we only probe for bandwidth in the beginning of a call right now. | 347 // we only probe for bandwidth in the beginning of a call right now. |
| 355 } | 348 } |
| 356 } | 349 } |
| 357 | 350 |
| 358 void RemoteBitrateEstimatorAbsSendTime::OnRttUpdate(int64_t avg_rtt_ms, | 351 void DelayBasedProbingEstimator::OnRttUpdate(int64_t avg_rtt_ms, |
| 359 int64_t max_rtt_ms) { | 352 int64_t max_rtt_ms) { |
| 360 rtc::CritScope lock(&crit_); | 353 rtc::CritScope lock(&crit_); |
| 361 remote_rate_.SetRtt(avg_rtt_ms); | 354 remote_rate_.SetRtt(avg_rtt_ms); |
| 362 } | 355 } |
| 363 | 356 |
| 364 void RemoteBitrateEstimatorAbsSendTime::RemoveStream(uint32_t ssrc) { | 357 void DelayBasedProbingEstimator::RemoveStream(uint32_t ssrc) { |
| 365 rtc::CritScope lock(&crit_); | 358 rtc::CritScope lock(&crit_); |
| 366 ssrcs_.erase(ssrc); | 359 ssrcs_.erase(ssrc); |
| 367 } | 360 } |
| 368 | 361 |
| 369 bool RemoteBitrateEstimatorAbsSendTime::LatestEstimate( | 362 bool DelayBasedProbingEstimator::LatestEstimate(std::vector<uint32_t>* ssrcs, |
| 370 std::vector<uint32_t>* ssrcs, | 363 uint32_t* bitrate_bps) const { |
| 371 uint32_t* bitrate_bps) const { | |
| 372 // Currently accessed from both the process thread (see | 364 // Currently accessed from both the process thread (see |
| 373 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see | 365 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see |
| 374 // Call::GetStats()). Should in the future only be accessed from a single | 366 // Call::GetStats()). Should in the future only be accessed from a single |
| 375 // thread. | 367 // thread. |
| 376 RTC_DCHECK(ssrcs); | 368 RTC_DCHECK(ssrcs); |
| 377 RTC_DCHECK(bitrate_bps); | 369 RTC_DCHECK(bitrate_bps); |
| 378 rtc::CritScope lock(&crit_); | 370 rtc::CritScope lock(&crit_); |
| 379 if (!remote_rate_.ValidEstimate()) { | 371 if (!remote_rate_.ValidEstimate()) { |
| 380 return false; | 372 return false; |
| 381 } | 373 } |
| 382 *ssrcs = Keys(ssrcs_); | 374 *ssrcs = Keys(ssrcs_); |
| 383 if (ssrcs_.empty()) { | 375 if (ssrcs_.empty()) { |
| 384 *bitrate_bps = 0; | 376 *bitrate_bps = 0; |
| 385 } else { | 377 } else { |
| 386 *bitrate_bps = remote_rate_.LatestEstimate(); | 378 *bitrate_bps = remote_rate_.LatestEstimate(); |
| 387 } | 379 } |
| 388 return true; | 380 return true; |
| 389 } | 381 } |
| 390 | 382 |
| 391 void RemoteBitrateEstimatorAbsSendTime::SetMinBitrate(int min_bitrate_bps) { | 383 void DelayBasedProbingEstimator::SetMinBitrate(int min_bitrate_bps) { |
| 392 // Called from both the configuration thread and the network thread. Shouldn't | 384 // Called from both the configuration thread and the network thread. Shouldn't |
| 393 // be called from the network thread in the future. | 385 // be called from the network thread in the future. |
| 394 rtc::CritScope lock(&crit_); | 386 rtc::CritScope lock(&crit_); |
| 395 remote_rate_.SetMinBitrate(min_bitrate_bps); | 387 remote_rate_.SetMinBitrate(min_bitrate_bps); |
| 396 } | 388 } |
| 397 } // namespace webrtc | 389 } // namespace webrtc |
| OLD | NEW |