Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: webrtc/modules/pacing/bitrate_prober.cc

Issue 1946173002: Bitrate prober now keep track of probing cluster id. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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/pacing/bitrate_prober.h" 11 #include "webrtc/modules/pacing/bitrate_prober.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <algorithm> 14 #include <algorithm>
15 #include <limits> 15 #include <limits>
16 #include <sstream> 16 #include <sstream>
17 17
18 #include "webrtc/base/checks.h"
18 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
19 #include "webrtc/modules/pacing/paced_sender.h" 20 #include "webrtc/modules/pacing/paced_sender.h"
20 21
21 namespace webrtc { 22 namespace webrtc {
22 23
23 namespace { 24 namespace {
24 int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) { 25 int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) {
25 assert(bitrate_bps > 0); 26 assert(bitrate_bps > 0);
26 // Compute the time delta needed to send packet_size bytes at bitrate_bps 27 // Compute the time delta needed to send packet_size bytes at bitrate_bps
27 // bps. Result is in milliseconds. 28 // bps. Result is in milliseconds.
28 return static_cast<int>(1000ll * static_cast<int64_t>(packet_size) * 8ll / 29 return static_cast<int>(1000ll * static_cast<int64_t>(packet_size) * 8ll /
29 bitrate_bps); 30 bitrate_bps);
30 } 31 }
31 } // namespace 32 } // namespace
32 33
33 BitrateProber::BitrateProber() 34 BitrateProber::BitrateProber()
34 : probing_state_(kDisabled), 35 : probing_state_(kDisabled),
35 packet_size_last_send_(0), 36 packet_size_last_send_(0),
36 time_last_send_ms_(-1) { 37 time_last_send_ms_(-1),
37 } 38 cluster_id_(0) {}
38 39
39 void BitrateProber::SetEnabled(bool enable) { 40 void BitrateProber::SetEnabled(bool enable) {
40 if (enable) { 41 if (enable) {
41 if (probing_state_ == kDisabled) { 42 if (probing_state_ == kDisabled) {
42 probing_state_ = kAllowedToProbe; 43 probing_state_ = kAllowedToProbe;
43 LOG(LS_INFO) << "Initial bandwidth probing enabled"; 44 LOG(LS_INFO) << "Initial bandwidth probing enabled";
44 } 45 }
45 } else { 46 } else {
46 probing_state_ = kDisabled; 47 probing_state_ = kDisabled;
47 LOG(LS_INFO) << "Initial bandwidth probing disabled"; 48 LOG(LS_INFO) << "Initial bandwidth probing disabled";
48 } 49 }
49 } 50 }
50 51
51 bool BitrateProber::IsProbing() const { 52 bool BitrateProber::IsProbing() const {
52 return probing_state_ == kProbing; 53 return probing_state_ == kProbing;
53 } 54 }
54 55
55 void BitrateProber::OnIncomingPacket(uint32_t bitrate_bps, 56 void BitrateProber::OnIncomingPacket(uint32_t bitrate_bps,
56 size_t packet_size, 57 size_t packet_size,
57 int64_t now_ms) { 58 int64_t now_ms) {
58 // Don't initialize probing unless we have something large enough to start 59 // Don't initialize probing unless we have something large enough to start
59 // probing. 60 // probing.
60 if (packet_size < PacedSender::kMinProbePacketSize) 61 if (packet_size < PacedSender::kMinProbePacketSize)
61 return; 62 return;
62 if (probing_state_ != kAllowedToProbe) 63 if (probing_state_ != kAllowedToProbe)
63 return; 64 return;
64 probe_bitrates_.clear();
65 // Max number of packets used for probing. 65 // Max number of packets used for probing.
66 const int kMaxNumProbes = 2; 66 const int kMaxNumProbes = 2;
67 const int kPacketsPerProbe = 5; 67 const int kPacketsPerProbe = 5;
68 const float kProbeBitrateMultipliers[kMaxNumProbes] = {3, 6}; 68 const float kProbeBitrateMultipliers[kMaxNumProbes] = {3, 6};
69 uint32_t bitrates_bps[kMaxNumProbes];
70 std::stringstream bitrate_log; 69 std::stringstream bitrate_log;
71 bitrate_log << "Start probing for bandwidth, bitrates:"; 70 bitrate_log << "Start probing for bandwidth, bitrates:";
72 for (int i = 0; i < kMaxNumProbes; ++i) { 71 for (int i = 0; i < kMaxNumProbes; ++i) {
73 bitrates_bps[i] = kProbeBitrateMultipliers[i] * bitrate_bps; 72 ProbeCluster cluster;
74 bitrate_log << " " << bitrates_bps[i]; 73 // We need one extra to get 5 deltas for the first probe, therefore (i == 0)
75 // We need one extra to get 5 deltas for the first probe. 74 cluster.max_probe_packets = kPacketsPerProbe + (i == 0 ? 1 : 0);
76 if (i == 0) 75 cluster.probe_bitrate_bps = kProbeBitrateMultipliers[i] * bitrate_bps;
77 probe_bitrates_.push_back(bitrates_bps[i]); 76 cluster.id = cluster_id_++;
78 for (int j = 0; j < kPacketsPerProbe; ++j) 77
79 probe_bitrates_.push_back(bitrates_bps[i]); 78 bitrate_log << " " << cluster.probe_bitrate_bps;
79 bitrate_log << ", num packets: " << cluster.max_probe_packets;
80
81 clusters_.push(cluster);
80 } 82 }
81 bitrate_log << ", num packets: " << probe_bitrates_.size();
82 LOG(LS_INFO) << bitrate_log.str().c_str(); 83 LOG(LS_INFO) << bitrate_log.str().c_str();
83 // Set last send time to current time so TimeUntilNextProbe doesn't short 84 // Set last send time to current time so TimeUntilNextProbe doesn't short
84 // circuit due to inactivity. 85 // circuit due to inactivity.
85 time_last_send_ms_ = now_ms; 86 time_last_send_ms_ = now_ms;
86 probing_state_ = kProbing; 87 probing_state_ = kProbing;
87 } 88 }
88 89
89 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { 90 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
90 if (probing_state_ != kDisabled && probe_bitrates_.empty()) { 91 if (probing_state_ != kDisabled && clusters_.empty()) {
91 probing_state_ = kWait; 92 probing_state_ = kWait;
92 } 93 }
93 if (probe_bitrates_.empty() || time_last_send_ms_ == -1) { 94
95 if (clusters_.empty() || time_last_send_ms_ == -1) {
94 // No probe started, probe finished, or too long since last probe packet. 96 // No probe started, probe finished, or too long since last probe packet.
95 return -1; 97 return -1;
96 } 98 }
97 int64_t elapsed_time_ms = now_ms - time_last_send_ms_; 99 int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
98 // If no packets have been sent for n milliseconds, temporarily deactivate to 100 // If no packets have been sent for n milliseconds, temporarily deactivate to
99 // not keep spinning. 101 // not keep spinning.
100 static const int kInactiveSendDeltaMs = 5000; 102 static const int kInactiveSendDeltaMs = 5000;
101 if (elapsed_time_ms > kInactiveSendDeltaMs) { 103 if (elapsed_time_ms > kInactiveSendDeltaMs) {
102 time_last_send_ms_ = -1; 104 time_last_send_ms_ = -1;
103 probing_state_ = kAllowedToProbe; 105 probing_state_ = kAllowedToProbe;
104 return -1; 106 return -1;
105 } 107 }
106 // We will send the first probe packet immediately if no packet has been 108 // We will send the first probe packet immediately if no packet has been
107 // sent before. 109 // sent before.
108 int time_until_probe_ms = 0; 110 int time_until_probe_ms = 0;
109 if (packet_size_last_send_ != 0 && probing_state_ == kProbing) { 111 if (packet_size_last_send_ != 0 && probing_state_ == kProbing) {
110 int next_delta_ms = ComputeDeltaFromBitrate(packet_size_last_send_, 112 int next_delta_ms = ComputeDeltaFromBitrate(
111 probe_bitrates_.front()); 113 packet_size_last_send_, clusters_.front().probe_bitrate_bps);
112 time_until_probe_ms = next_delta_ms - elapsed_time_ms; 114 time_until_probe_ms = next_delta_ms - elapsed_time_ms;
113 // There is no point in trying to probe with less than 1 ms between packets 115 // There is no point in trying to probe with less than 1 ms between packets
114 // as it essentially means trying to probe at infinite bandwidth. 116 // as it essentially means trying to probe at infinite bandwidth.
115 const int kMinProbeDeltaMs = 1; 117 const int kMinProbeDeltaMs = 1;
116 // If we have waited more than 3 ms for a new packet to probe with we will 118 // If we have waited more than 3 ms for a new packet to probe with we will
117 // consider this probing session over. 119 // consider this probing session over.
118 const int kMaxProbeDelayMs = 3; 120 const int kMaxProbeDelayMs = 3;
119 if (next_delta_ms < kMinProbeDeltaMs || 121 if (next_delta_ms < kMinProbeDeltaMs ||
120 time_until_probe_ms < -kMaxProbeDelayMs) { 122 time_until_probe_ms < -kMaxProbeDelayMs) {
121 // We currently disable probing after the first probe, as we only want 123 // We currently disable probing after the first probe, as we only want
122 // to probe at the beginning of a connection. We should set this to 124 // to probe at the beginning of a connection. We should set this to
123 // kWait if we later want to probe periodically. 125 // kWait if we later want to probe periodically.
124 probing_state_ = kWait; 126 probing_state_ = kWait;
125 LOG(LS_INFO) << "Next delta too small, stop probing."; 127 LOG(LS_INFO) << "Next delta too small, stop probing.";
126 time_until_probe_ms = 0; 128 time_until_probe_ms = 0;
127 } 129 }
128 } 130 }
129 return std::max(time_until_probe_ms, 0); 131 return std::max(time_until_probe_ms, 0);
130 } 132 }
131 133
134 int BitrateProber::CurrentClusterId() const {
135 RTC_DCHECK(!clusters_.empty());
136 RTC_DCHECK_EQ(kProbing, probing_state_);
137 return clusters_.front().id;
138 }
139
132 size_t BitrateProber::RecommendedPacketSize() const { 140 size_t BitrateProber::RecommendedPacketSize() const {
133 return packet_size_last_send_; 141 return packet_size_last_send_;
134 } 142 }
135 143
136 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { 144 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
137 assert(packet_size > 0); 145 assert(packet_size > 0);
138 if (packet_size < PacedSender::kMinProbePacketSize) 146 if (packet_size < PacedSender::kMinProbePacketSize)
139 return; 147 return;
140 packet_size_last_send_ = packet_size; 148 packet_size_last_send_ = packet_size;
141 time_last_send_ms_ = now_ms; 149 time_last_send_ms_ = now_ms;
142 if (probing_state_ != kProbing) 150 if (probing_state_ != kProbing)
143 return; 151 return;
144 if (!probe_bitrates_.empty()) 152 if (!clusters_.empty()) {
145 probe_bitrates_.pop_front(); 153 ProbeCluster* cluster = &clusters_.front();
154 ++cluster->sent_probe_packets;
155 if (cluster->sent_probe_packets == cluster->max_probe_packets)
156 clusters_.pop();
157 }
146 } 158 }
147 } // namespace webrtc 159 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/pacing/bitrate_prober.h ('k') | webrtc/modules/pacing/bitrate_prober_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698