| Index: webrtc/modules/pacing/bitrate_prober.cc
|
| diff --git a/webrtc/modules/pacing/bitrate_prober.cc b/webrtc/modules/pacing/bitrate_prober.cc
|
| index 8e3c5e354795a17a6c9ed32c4e4e9b3343294186..bdf48fda1de5a793fb68f3545a16ba842f184c60 100644
|
| --- a/webrtc/modules/pacing/bitrate_prober.cc
|
| +++ b/webrtc/modules/pacing/bitrate_prober.cc
|
| @@ -20,9 +20,6 @@ namespace webrtc {
|
|
|
| namespace {
|
|
|
| -// Inactivity threshold above which probing is restarted.
|
| -constexpr int kInactivityThresholdMs = 5000;
|
| -
|
| // A minimum interval between probes to allow scheduling to be feasible.
|
| constexpr int kMinProbeDeltaMs = 1;
|
|
|
| @@ -32,18 +29,18 @@ constexpr int kMinProbePacketsSent = 5;
|
| // The minimum probing duration in ms.
|
| constexpr int kMinProbeDurationMs = 15;
|
|
|
| -int ComputeDeltaFromBitrate(size_t probe_size, uint32_t bitrate_bps) {
|
| - RTC_CHECK_GT(bitrate_bps, 0);
|
| - // Compute the time delta needed to send probe_size bytes at bitrate_bps
|
| - // bps. Result is in milliseconds.
|
| - return static_cast<int>((1000ll * probe_size * 8) / bitrate_bps);
|
| -}
|
| +// Maximum amount of time each probe can be delayed. Probe cluster is reset and
|
| +// retried from the start when this limit is reached.
|
| +constexpr int kMaxProbeDelayMs = 3;
|
| +
|
| +// Number of times probing is retried before the cluster is dropped.
|
| +constexpr int kMaxRetryAttempts = 3;
|
| +
|
| } // namespace
|
|
|
| BitrateProber::BitrateProber()
|
| : probing_state_(ProbingState::kDisabled),
|
| - probe_size_last_sent_(0),
|
| - time_last_probe_sent_ms_(-1),
|
| + next_probe_time_ms_(-1),
|
| next_cluster_id_(0) {
|
| SetEnabled(true);
|
| }
|
| @@ -70,6 +67,8 @@ void BitrateProber::OnIncomingPacket(size_t packet_size) {
|
| if (probing_state_ == ProbingState::kInactive &&
|
| !clusters_.empty() &&
|
| packet_size >= PacedSender::kMinProbePacketSize) {
|
| + // Send next probe right away.
|
| + next_probe_time_ms_ = -1;
|
| probing_state_ = ProbingState::kActive;
|
| }
|
| }
|
| @@ -93,55 +92,36 @@ void BitrateProber::CreateProbeCluster(int bitrate_bps) {
|
| }
|
|
|
| void BitrateProber::ResetState() {
|
| - time_last_probe_sent_ms_ = -1;
|
| - probe_size_last_sent_ = 0;
|
| + RTC_DCHECK(probing_state_ == ProbingState::kActive);
|
|
|
| // Recreate all probing clusters.
|
| std::queue<ProbeCluster> clusters;
|
| clusters.swap(clusters_);
|
| while (!clusters.empty()) {
|
| - CreateProbeCluster(clusters.front().bitrate_bps);
|
| + if (clusters.front().retries < kMaxRetryAttempts) {
|
| + CreateProbeCluster(clusters.front().bitrate_bps);
|
| + clusters_.back().retries = clusters.front().retries + 1;
|
| + }
|
| clusters.pop();
|
| }
|
| - // If its enabled, reset to inactive.
|
| - if (probing_state_ != ProbingState::kDisabled)
|
| - probing_state_ = ProbingState::kInactive;
|
| +
|
| + probing_state_ = ProbingState::kInactive;
|
| }
|
|
|
| int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
|
| // Probing is not active or probing is already complete.
|
| if (probing_state_ != ProbingState::kActive || clusters_.empty())
|
| return -1;
|
| - // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent.
|
| - int64_t elapsed_time_ms;
|
| - if (time_last_probe_sent_ms_ == -1) {
|
| - elapsed_time_ms = 0;
|
| - } else {
|
| - elapsed_time_ms = now_ms - time_last_probe_sent_ms_;
|
| - }
|
| - // If no probes have been sent for a while, abort current probing and
|
| - // reset.
|
| - if (elapsed_time_ms > kInactivityThresholdMs) {
|
| - ResetState();
|
| - return -1;
|
| - }
|
| - // We will send the first probe packet immediately if no packet has been
|
| - // sent before.
|
| +
|
| int time_until_probe_ms = 0;
|
| - if (probe_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) {
|
| - int next_delta_ms = ComputeDeltaFromBitrate(probe_size_last_sent_,
|
| - clusters_.front().bitrate_bps);
|
| - time_until_probe_ms = next_delta_ms - elapsed_time_ms;
|
| - // If we have waited more than 3 ms for a new packet to probe with we will
|
| - // consider this probing session over.
|
| - const int kMaxProbeDelayMs = 3;
|
| - if (next_delta_ms < kMinProbeDeltaMs ||
|
| - time_until_probe_ms < -kMaxProbeDelayMs) {
|
| - probing_state_ = ProbingState::kSuspended;
|
| - LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend";
|
| - time_until_probe_ms = 0;
|
| + if (next_probe_time_ms_ >= 0) {
|
| + time_until_probe_ms = next_probe_time_ms_ - now_ms;
|
| + if (time_until_probe_ms < -kMaxProbeDelayMs) {
|
| + ResetState();
|
| + return -1;
|
| }
|
| }
|
| +
|
| return std::max(time_until_probe_ms, 0);
|
| }
|
|
|
| @@ -162,12 +142,16 @@ size_t BitrateProber::RecommendedMinProbeSize() const {
|
| void BitrateProber::ProbeSent(int64_t now_ms, size_t bytes) {
|
| RTC_DCHECK(probing_state_ == ProbingState::kActive);
|
| RTC_DCHECK_GT(bytes, 0);
|
| - probe_size_last_sent_ = bytes;
|
| - time_last_probe_sent_ms_ = now_ms;
|
| +
|
| if (!clusters_.empty()) {
|
| ProbeCluster* cluster = &clusters_.front();
|
| + if (cluster->sent_probes == 0) {
|
| + RTC_DCHECK_EQ(cluster->time_started_ms, -1);
|
| + cluster->time_started_ms = now_ms;
|
| + }
|
| cluster->sent_bytes += static_cast<int>(bytes);
|
| cluster->sent_probes += 1;
|
| + next_probe_time_ms_ = GetNextProbeTime(clusters_.front());
|
| if (cluster->sent_bytes >= cluster->min_bytes &&
|
| cluster->sent_probes >= cluster->min_probes) {
|
| clusters_.pop();
|
| @@ -176,4 +160,17 @@ void BitrateProber::ProbeSent(int64_t now_ms, size_t bytes) {
|
| probing_state_ = ProbingState::kSuspended;
|
| }
|
| }
|
| +
|
| +int64_t BitrateProber::GetNextProbeTime(const ProbeCluster& cluster) {
|
| + RTC_CHECK_GT(cluster.bitrate_bps, 0);
|
| + RTC_CHECK_GE(cluster.time_started_ms, 0);
|
| +
|
| + // Compute the time delta from the cluster start to ensure probe bitrate stays
|
| + // close to the target bitrate. Result is in milliseconds.
|
| + int64_t delta_ms = (8000ll * cluster.sent_bytes + cluster.bitrate_bps / 2) /
|
| + cluster.bitrate_bps;
|
| + return cluster.time_started_ms + delta_ms;
|
| +}
|
| +
|
| +
|
| } // namespace webrtc
|
|
|