LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/common_video - bitrate_adjuster.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 80 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 2016 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/common_video/include/bitrate_adjuster.h"
      12             : 
      13             : #include <algorithm>
      14             : #include <cmath>
      15             : 
      16             : #include "webrtc/base/checks.h"
      17             : #include "webrtc/base/logging.h"
      18             : #include "webrtc/system_wrappers/include/clock.h"
      19             : 
      20             : namespace webrtc {
      21             : 
      22             : // Update bitrate at most once every second.
      23             : const uint32_t BitrateAdjuster::kBitrateUpdateIntervalMs = 1000;
      24             : 
      25             : // Update bitrate at most once every 30 frames.
      26             : const uint32_t BitrateAdjuster::kBitrateUpdateFrameInterval = 30;
      27             : 
      28             : // 10 percent of original.
      29             : const float BitrateAdjuster::kBitrateTolerancePct = .1f;
      30             : 
      31             : const float BitrateAdjuster::kBytesPerMsToBitsPerSecond = 8 * 1000;
      32             : 
      33           0 : BitrateAdjuster::BitrateAdjuster(Clock* clock,
      34             :                                  float min_adjusted_bitrate_pct,
      35           0 :                                  float max_adjusted_bitrate_pct)
      36             :     : clock_(clock),
      37             :       min_adjusted_bitrate_pct_(min_adjusted_bitrate_pct),
      38             :       max_adjusted_bitrate_pct_(max_adjusted_bitrate_pct),
      39             :       bitrate_tracker_(1.5 * kBitrateUpdateIntervalMs,
      40           0 :                        kBytesPerMsToBitsPerSecond) {
      41           0 :   Reset();
      42           0 : }
      43             : 
      44           0 : void BitrateAdjuster::SetTargetBitrateBps(uint32_t bitrate_bps) {
      45           0 :   rtc::CritScope cs(&crit_);
      46             :   // If the change in target bitrate is large, update the adjusted bitrate
      47             :   // immediately since it's likely we have gained or lost a sizeable amount of
      48             :   // bandwidth and we'll want to respond quickly.
      49             :   // If the change in target bitrate fits within the existing tolerance of
      50             :   // encoder output, wait for the next adjustment time to preserve
      51             :   // existing penalties and not forcibly reset the adjusted bitrate to target.
      52             :   // However, if we received many small deltas within an update time
      53             :   // window and one of them exceeds the tolerance when compared to the last
      54             :   // target we updated against, treat it as a large change in target bitrate.
      55           0 :   if (!IsWithinTolerance(bitrate_bps, target_bitrate_bps_) ||
      56           0 :       !IsWithinTolerance(bitrate_bps, last_adjusted_target_bitrate_bps_)) {
      57           0 :     adjusted_bitrate_bps_ = bitrate_bps;
      58           0 :     last_adjusted_target_bitrate_bps_ = bitrate_bps;
      59             :   }
      60           0 :   target_bitrate_bps_ = bitrate_bps;
      61           0 : }
      62             : 
      63           0 : uint32_t BitrateAdjuster::GetTargetBitrateBps() const {
      64           0 :   rtc::CritScope cs(&crit_);
      65           0 :   return target_bitrate_bps_;
      66             : }
      67             : 
      68           0 : uint32_t BitrateAdjuster::GetAdjustedBitrateBps() const {
      69           0 :   rtc::CritScope cs(&crit_);
      70           0 :   return adjusted_bitrate_bps_;
      71             : }
      72             : 
      73           0 : rtc::Optional<uint32_t> BitrateAdjuster::GetEstimatedBitrateBps() {
      74           0 :   rtc::CritScope cs(&crit_);
      75           0 :   return bitrate_tracker_.Rate(clock_->TimeInMilliseconds());
      76             : }
      77             : 
      78           0 : void BitrateAdjuster::Update(size_t frame_size) {
      79           0 :   rtc::CritScope cs(&crit_);
      80           0 :   uint32_t current_time_ms = clock_->TimeInMilliseconds();
      81           0 :   bitrate_tracker_.Update(frame_size, current_time_ms);
      82           0 :   UpdateBitrate(current_time_ms);
      83           0 : }
      84             : 
      85           0 : bool BitrateAdjuster::IsWithinTolerance(uint32_t bitrate_bps,
      86             :                                         uint32_t target_bitrate_bps) {
      87           0 :   if (target_bitrate_bps == 0) {
      88           0 :     return false;
      89             :   }
      90           0 :   float delta = std::abs(static_cast<float>(bitrate_bps) -
      91           0 :                          static_cast<float>(target_bitrate_bps));
      92           0 :   float delta_pct = delta / target_bitrate_bps;
      93           0 :   return delta_pct < kBitrateTolerancePct;
      94             : }
      95             : 
      96           0 : uint32_t BitrateAdjuster::GetMinAdjustedBitrateBps() const {
      97           0 :   return min_adjusted_bitrate_pct_ * target_bitrate_bps_;
      98             : }
      99             : 
     100           0 : uint32_t BitrateAdjuster::GetMaxAdjustedBitrateBps() const {
     101           0 :   return max_adjusted_bitrate_pct_ * target_bitrate_bps_;
     102             : }
     103             : 
     104             : // Only safe to call this after Update calls have stopped
     105           0 : void BitrateAdjuster::Reset() {
     106           0 :   rtc::CritScope cs(&crit_);
     107           0 :   target_bitrate_bps_ = 0;
     108           0 :   adjusted_bitrate_bps_ = 0;
     109           0 :   last_adjusted_target_bitrate_bps_ = 0;
     110           0 :   last_bitrate_update_time_ms_ = 0;
     111           0 :   frames_since_last_update_ = 0;
     112           0 :   bitrate_tracker_.Reset();
     113           0 : }
     114             : 
     115           0 : void BitrateAdjuster::UpdateBitrate(uint32_t current_time_ms) {
     116             :   uint32_t time_since_last_update_ms =
     117           0 :       current_time_ms - last_bitrate_update_time_ms_;
     118             :   // Don't attempt to update bitrate unless enough time and frames have passed.
     119           0 :   ++frames_since_last_update_;
     120           0 :   if (time_since_last_update_ms < kBitrateUpdateIntervalMs ||
     121           0 :       frames_since_last_update_ < kBitrateUpdateFrameInterval) {
     122           0 :     return;
     123             :   }
     124           0 :   float target_bitrate_bps = target_bitrate_bps_;
     125             :   float estimated_bitrate_bps =
     126           0 :       bitrate_tracker_.Rate(current_time_ms).value_or(target_bitrate_bps);
     127           0 :   float error = target_bitrate_bps - estimated_bitrate_bps;
     128             : 
     129             :   // Adjust if we've overshot by any amount or if we've undershot too much.
     130           0 :   if (estimated_bitrate_bps > target_bitrate_bps ||
     131           0 :       error > kBitrateTolerancePct * target_bitrate_bps) {
     132             :     // Adjust the bitrate by a fraction of the error.
     133           0 :     float adjustment = .5 * error;
     134           0 :     float adjusted_bitrate_bps = target_bitrate_bps + adjustment;
     135             : 
     136             :     // Clamp the adjustment.
     137           0 :     float min_bitrate_bps = GetMinAdjustedBitrateBps();
     138           0 :     float max_bitrate_bps = GetMaxAdjustedBitrateBps();
     139           0 :     adjusted_bitrate_bps = std::max(adjusted_bitrate_bps, min_bitrate_bps);
     140           0 :     adjusted_bitrate_bps = std::min(adjusted_bitrate_bps, max_bitrate_bps);
     141             : 
     142             :     // Set the adjustment if it's not already set.
     143           0 :     float last_adjusted_bitrate_bps = adjusted_bitrate_bps_;
     144           0 :     if (adjusted_bitrate_bps != last_adjusted_bitrate_bps) {
     145           0 :       LOG(LS_VERBOSE) << "Adjusting encoder bitrate:"
     146           0 :                       << "\n  target_bitrate:"
     147           0 :                       << static_cast<uint32_t>(target_bitrate_bps)
     148           0 :                       << "\n  estimated_bitrate:"
     149           0 :                       << static_cast<uint32_t>(estimated_bitrate_bps)
     150           0 :                       << "\n  last_adjusted_bitrate:"
     151           0 :                       << static_cast<uint32_t>(last_adjusted_bitrate_bps)
     152           0 :                       << "\n  adjusted_bitrate:"
     153           0 :                       << static_cast<uint32_t>(adjusted_bitrate_bps);
     154           0 :       adjusted_bitrate_bps_ = adjusted_bitrate_bps;
     155             :     }
     156             :   }
     157           0 :   last_bitrate_update_time_ms_ = current_time_ms;
     158           0 :   frames_since_last_update_ = 0;
     159           0 :   last_adjusted_target_bitrate_bps_ = target_bitrate_bps_;
     160             : }
     161             : 
     162             : }  // namespace webrtc

Generated by: LCOV version 1.13