LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/pacing - bitrate_prober.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 90 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/pacing/bitrate_prober.h"
      12             : 
      13             : #include <algorithm>
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/logging.h"
      17             : #include "webrtc/modules/pacing/paced_sender.h"
      18             : 
      19             : namespace webrtc {
      20             : 
      21             : namespace {
      22             : 
      23             : // Inactivity threshold above which probing is restarted.
      24             : constexpr int kInactivityThresholdMs = 5000;
      25             : 
      26             : // A minimum interval between probes to allow scheduling to be feasible.
      27             : constexpr int kMinProbeDeltaMs = 1;
      28             : 
      29             : // The minimum number probing packets used.
      30             : constexpr int kMinProbePacketsSent = 5;
      31             : 
      32             : // The minimum probing duration in ms.
      33             : constexpr int kMinProbeDurationMs = 15;
      34             : 
      35           0 : int ComputeDeltaFromBitrate(size_t probe_size, uint32_t bitrate_bps) {
      36           0 :   RTC_CHECK_GT(bitrate_bps, 0);
      37             :   // Compute the time delta needed to send probe_size bytes at bitrate_bps
      38             :   // bps. Result is in milliseconds.
      39           0 :   return static_cast<int>((1000ll * probe_size * 8) / bitrate_bps);
      40             : }
      41             : }  // namespace
      42             : 
      43           0 : BitrateProber::BitrateProber()
      44             :     : probing_state_(ProbingState::kDisabled),
      45             :       probe_size_last_sent_(0),
      46             :       time_last_probe_sent_ms_(-1),
      47           0 :       next_cluster_id_(0) {
      48           0 :   SetEnabled(true);
      49           0 : }
      50             : 
      51           0 : void BitrateProber::SetEnabled(bool enable) {
      52           0 :   if (enable) {
      53           0 :     if (probing_state_ == ProbingState::kDisabled) {
      54           0 :       probing_state_ = ProbingState::kInactive;
      55           0 :       LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive";
      56             :     }
      57             :   } else {
      58           0 :     probing_state_ = ProbingState::kDisabled;
      59           0 :     LOG(LS_INFO) << "Bandwidth probing disabled";
      60             :   }
      61           0 : }
      62             : 
      63           0 : bool BitrateProber::IsProbing() const {
      64           0 :   return probing_state_ == ProbingState::kActive;
      65             : }
      66             : 
      67           0 : void BitrateProber::OnIncomingPacket(size_t packet_size) {
      68             :   // Don't initialize probing unless we have something large enough to start
      69             :   // probing.
      70           0 :   if (probing_state_ == ProbingState::kInactive &&
      71           0 :       !clusters_.empty() &&
      72             :       packet_size >= PacedSender::kMinProbePacketSize) {
      73           0 :     probing_state_ = ProbingState::kActive;
      74             :   }
      75           0 : }
      76             : 
      77           0 : void BitrateProber::CreateProbeCluster(int bitrate_bps) {
      78           0 :   RTC_DCHECK(probing_state_ != ProbingState::kDisabled);
      79           0 :   ProbeCluster cluster;
      80           0 :   cluster.min_probes = kMinProbePacketsSent;
      81           0 :   cluster.min_bytes = bitrate_bps * kMinProbeDurationMs / 8000;
      82           0 :   cluster.bitrate_bps = bitrate_bps;
      83           0 :   cluster.id = next_cluster_id_++;
      84           0 :   clusters_.push(cluster);
      85             : 
      86           0 :   LOG(LS_INFO) << "Probe cluster (bitrate:min bytes:min packets): ("
      87           0 :                << cluster.bitrate_bps << ":" << cluster.min_bytes << ":"
      88           0 :                << cluster.min_probes << ")";
      89             :   // If we are already probing, continue to do so. Otherwise set it to
      90             :   // kInactive and wait for OnIncomingPacket to start the probing.
      91           0 :   if (probing_state_ != ProbingState::kActive)
      92           0 :     probing_state_ = ProbingState::kInactive;
      93           0 : }
      94             : 
      95           0 : void BitrateProber::ResetState() {
      96           0 :   time_last_probe_sent_ms_ = -1;
      97           0 :   probe_size_last_sent_ = 0;
      98             : 
      99             :   // Recreate all probing clusters.
     100           0 :   std::queue<ProbeCluster> clusters;
     101           0 :   clusters.swap(clusters_);
     102           0 :   while (!clusters.empty()) {
     103           0 :     CreateProbeCluster(clusters.front().bitrate_bps);
     104           0 :     clusters.pop();
     105             :   }
     106             :   // If its enabled, reset to inactive.
     107           0 :   if (probing_state_ != ProbingState::kDisabled)
     108           0 :     probing_state_ = ProbingState::kInactive;
     109           0 : }
     110             : 
     111           0 : int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
     112             :   // Probing is not active or probing is already complete.
     113           0 :   if (probing_state_ != ProbingState::kActive || clusters_.empty())
     114           0 :     return -1;
     115             :   // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent.
     116             :   int64_t elapsed_time_ms;
     117           0 :   if (time_last_probe_sent_ms_ == -1) {
     118           0 :     elapsed_time_ms = 0;
     119             :   } else {
     120           0 :     elapsed_time_ms = now_ms - time_last_probe_sent_ms_;
     121             :   }
     122             :   // If no probes have been sent for a while, abort current probing and
     123             :   // reset.
     124           0 :   if (elapsed_time_ms > kInactivityThresholdMs) {
     125           0 :     ResetState();
     126           0 :     return -1;
     127             :   }
     128             :   // We will send the first probe packet immediately if no packet has been
     129             :   // sent before.
     130           0 :   int time_until_probe_ms = 0;
     131           0 :   if (probe_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) {
     132           0 :     int next_delta_ms = ComputeDeltaFromBitrate(probe_size_last_sent_,
     133           0 :                                                 clusters_.front().bitrate_bps);
     134           0 :     time_until_probe_ms = next_delta_ms - elapsed_time_ms;
     135             :     // If we have waited more than 3 ms for a new packet to probe with we will
     136             :     // consider this probing session over.
     137           0 :     const int kMaxProbeDelayMs = 3;
     138           0 :     if (next_delta_ms < kMinProbeDeltaMs ||
     139           0 :         time_until_probe_ms < -kMaxProbeDelayMs) {
     140           0 :       probing_state_ = ProbingState::kSuspended;
     141           0 :       LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend";
     142           0 :       time_until_probe_ms = 0;
     143             :     }
     144             :   }
     145           0 :   return std::max(time_until_probe_ms, 0);
     146             : }
     147             : 
     148           0 : int BitrateProber::CurrentClusterId() const {
     149           0 :   RTC_DCHECK(!clusters_.empty());
     150           0 :   RTC_DCHECK(ProbingState::kActive == probing_state_);
     151           0 :   return clusters_.front().id;
     152             : }
     153             : 
     154             : // Probe size is recommended based on the probe bitrate required. We choose
     155             : // a minimum of twice |kMinProbeDeltaMs| interval to allow scheduling to be
     156             : // feasible.
     157           0 : size_t BitrateProber::RecommendedMinProbeSize() const {
     158           0 :   RTC_DCHECK(!clusters_.empty());
     159           0 :   return clusters_.front().bitrate_bps * 2 * kMinProbeDeltaMs / (8 * 1000);
     160             : }
     161             : 
     162           0 : void BitrateProber::ProbeSent(int64_t now_ms, size_t bytes) {
     163           0 :   RTC_DCHECK(probing_state_ == ProbingState::kActive);
     164           0 :   RTC_DCHECK_GT(bytes, 0);
     165           0 :   probe_size_last_sent_ = bytes;
     166           0 :   time_last_probe_sent_ms_ = now_ms;
     167           0 :   if (!clusters_.empty()) {
     168           0 :     ProbeCluster* cluster = &clusters_.front();
     169           0 :     cluster->sent_bytes += static_cast<int>(bytes);
     170           0 :     cluster->sent_probes += 1;
     171           0 :     if (cluster->sent_bytes >= cluster->min_bytes &&
     172           0 :         cluster->sent_probes >= cluster->min_probes) {
     173           0 :       clusters_.pop();
     174             :     }
     175           0 :     if (clusters_.empty())
     176           0 :       probing_state_ = ProbingState::kSuspended;
     177             :   }
     178           0 : }
     179             : }  // namespace webrtc

Generated by: LCOV version 1.13