webrtc发送端带宽预测

  • 当接收侧感知到2-10%丢包率,发送端的预测值不变。
  • 当实际丢包率超过预测值10%时,新的预测值可更新为As_hat(i)= As_hat(i-1)(1-0.5p),其中p为丢包率。
  • 当实际丢包率小于2%时预测时可更新为As_hat(i)= 1.08(As_hat(i-1))+0.5+1000,其中p为丢包率。
  • 其中p是rtcp里的丢包率
void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) {
    uint32_t new_bitrate = current_bitrate_bps_;
    // We trust the REMB and/or delay-based estimate during the first 2 seconds if
    // we haven't had any packet loss reported, to allow startup bitrate probing.
    if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) {
        new_bitrate = std::max(bwe_incoming_, new_bitrate);
        new_bitrate = std::max(delay_based_bitrate_bps_, new_bitrate);

        if (new_bitrate != current_bitrate_bps_) {
            min_bitrate_history_.clear();
            min_bitrate_history_.push_back(
            std::make_pair(now_ms, current_bitrate_bps_));
            CapBitrateToThresholds(now_ms, new_bitrate);
            return;
        }
    }
    UpdateMinHistory(now_ms);
    if (last_packet_report_ms_ == -1) {
        // No feedback received.
        CapBitrateToThresholds(now_ms, current_bitrate_bps_);
        return;
    }
    int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_;
    int64_t time_since_feedback_ms = now_ms - last_feedback_ms_;
    if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) {
        // We only care about loss above a given bitrate threshold.
        float loss = last_fraction_loss_ / 256.0f;
        // We only make decisions based on loss when the bitrate is above a
        // threshold. This is a crude way of handling loss which is uncorrelated
        // to congestion.
        if (current_bitrate_bps_ < bitrate_threshold_bps_ ||
            loss <= low_loss_threshold_) {
            // Loss < 2%: Increase rate by 8% of the min bitrate in the last
            // kBweIncreaseIntervalMs.
            // Note that by remembering the bitrate over the last second one can
            // rampup up one second faster than if only allowed to start ramping
            // at 8% per second rate now. E.g.:
            // If sending a constant 100kbps it can rampup immediatly to 108kbps
            // whenever a receiver report is received with lower packet loss.
            // If instead one would do: current_bitrate_bps_ *= 1.08^(delta time),
            // it would take over one second since the lower packet loss to achieve
            // 108kbps.
            new_bitrate = static_cast(
                min_bitrate_history_.front().second * 1.08 + 0.5);

            // Add 1 kbps extra, just to make sure that we do not get stuck
            // (gives a little extra increase at low rates, negligible at higher
            // rates).
            new_bitrate += 1000;
    } else if (current_bitrate_bps_ > bitrate_threshold_bps_) {
            if (loss <= high_loss_threshold_) {
                // Loss between 2% - 10%: Do nothing.
            } else {
                // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs
                // + rtt.
                if (!has_decreased_since_last_fraction_loss_ &&
                    (now_ms - time_last_decrease_ms_) >=
                    (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) {
                    time_last_decrease_ms_ = now_ms;

                    // Reduce rate:
                    // newRate = rate * (1 - 0.5*lossRate);
                    // where packetLoss = 256*lossRate;
                    new_bitrate = static_cast(
                            (current_bitrate_bps_ *
                                static_cast(512 - last_fraction_loss_)) /
                            512.0);
                    has_decreased_since_last_fraction_loss_ = true;
                }
            }
        }
    } else if (time_since_feedback_ms >
        kFeedbackTimeoutIntervals * kFeedbackIntervalMs &&
            (last_timeout_ms_ == -1 ||
                    now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) {
            if (in_timeout_experiment_) {
                LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms
                << " ms), reducing bitrate.";
                new_bitrate *= 0.8;
                // Reset accumulators since we've already acted on missing feedback and
                // shouldn't to act again on these old lost packets.
                lost_packets_since_last_loss_update_Q8_ = 0;
                expected_packets_since_last_loss_update_ = 0;
                last_timeout_ms_ = now_ms;
            }
        }
    //其实就是估算current_bitrate_bps_
    CapBitrateToThresholds(now_ms, new_bitrate);
}
bitrate_threshold_bps_ 是怎么来的?
SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
    : lost_packets_since_last_loss_update_Q8_(0),
    expected_packets_since_last_loss_update_(0),
    current_bitrate_bps_(0),
    min_bitrate_configured_(congestion_controller::GetMinBitrateBps()),
    max_bitrate_configured_(kDefaultMaxBitrateBps),
    last_low_bitrate_log_ms_(-1),
    has_decreased_since_last_fraction_loss_(false),
    last_feedback_ms_(-1),
    last_packet_report_ms_(-1),
    last_timeout_ms_(-1),
    last_fraction_loss_(0),
    last_logged_fraction_loss_(0),
    last_round_trip_time_ms_(0),
    bwe_incoming_(0),
    delay_based_bitrate_bps_(0),
    time_last_decrease_ms_(0),
    first_report_time_ms_(-1),
    initially_lost_packets_(0),
    bitrate_at_2_seconds_kbps_(0),
    uma_update_state_(kNoUpdate),
    rampup_uma_stats_updated_(kNumUmaRampupMetrics, false),
    event_log_(event_log),
    last_rtc_event_log_ms_(-1),
    in_timeout_experiment_(
    webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")),
    low_loss_threshold_(kDefaultLowLossThreshold),
    high_loss_threshold_(kDefaultHighLossThreshold),
    bitrate_threshold_bps_(1000 * kDefaultBitrateThresholdKbps) {
    RTC_DCHECK(event_log);
    if (BweLossExperimentIsEnabled()) {
        uint32_t bitrate_threshold_kbps;
        if (ReadBweLossExperimentParameters(&low_loss_threshold_,
            &high_loss_threshold_,
            &bitrate_threshold_kbps)) {
            LOG(LS_INFO) << "Enabled BweLossExperiment with parameters "
            << low_loss_threshold_ << ", " << high_loss_threshold_
            << ", " << bitrate_threshold_kbps;
            bitrate_threshold_bps_ = bitrate_threshold_kbps * 1000;
        }
    }
}


你可能感兴趣的:(webrtc)