tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

receive_time_calculator.cc (5020B)


      1 /*
      2 *  Copyright (c) 2018 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 "call/receive_time_calculator.h"
     12 
     13 #include <cstdint>
     14 #include <memory>
     15 #include <string>
     16 
     17 #include "api/field_trials_view.h"
     18 #include "api/units/time_delta.h"
     19 #include "rtc_base/experiments/field_trial_parser.h"
     20 #include "rtc_base/numerics/safe_minmax.h"
     21 
     22 namespace webrtc {
     23 namespace {
     24 
     25 const char kBweReceiveTimeCorrection[] = "WebRTC-Bwe-ReceiveTimeFix";
     26 }  // namespace
     27 
     28 ReceiveTimeCalculatorConfig::ReceiveTimeCalculatorConfig(
     29    const FieldTrialsView& field_trials)
     30    : max_packet_time_repair("maxrep", TimeDelta::Millis(2000)),
     31      stall_threshold("stall", TimeDelta::Millis(5)),
     32      tolerance("tol", TimeDelta::Millis(1)),
     33      max_stall("maxstall", TimeDelta::Seconds(5)) {
     34  std::string trial_string = field_trials.Lookup(kBweReceiveTimeCorrection);
     35  ParseFieldTrial(
     36      {&max_packet_time_repair, &stall_threshold, &tolerance, &max_stall},
     37      trial_string);
     38 }
     39 ReceiveTimeCalculatorConfig::ReceiveTimeCalculatorConfig(
     40    const ReceiveTimeCalculatorConfig&) = default;
     41 ReceiveTimeCalculatorConfig::~ReceiveTimeCalculatorConfig() = default;
     42 
     43 ReceiveTimeCalculator::ReceiveTimeCalculator(
     44    const FieldTrialsView& field_trials)
     45    : config_(field_trials) {}
     46 
     47 std::unique_ptr<ReceiveTimeCalculator>
     48 ReceiveTimeCalculator::CreateFromFieldTrial(
     49    const FieldTrialsView& field_trials) {
     50  if (!field_trials.IsEnabled(kBweReceiveTimeCorrection))
     51    return nullptr;
     52  return std::make_unique<ReceiveTimeCalculator>(field_trials);
     53 }
     54 
     55 int64_t ReceiveTimeCalculator::ReconcileReceiveTimes(int64_t packet_time_us,
     56                                                     int64_t system_time_us,
     57                                                     int64_t safe_time_us) {
     58  int64_t stall_time_us = system_time_us - packet_time_us;
     59  if (total_system_time_passed_us_ < config_.stall_threshold->us()) {
     60    stall_time_us = SafeMin(stall_time_us, config_.max_stall->us());
     61  }
     62  int64_t corrected_time_us = safe_time_us - stall_time_us;
     63 
     64  if (last_packet_time_us_ == -1 && stall_time_us < 0) {
     65    static_clock_offset_us_ = stall_time_us;
     66    corrected_time_us += static_clock_offset_us_;
     67  } else if (last_packet_time_us_ > 0) {
     68    // All repairs depend on variables being intialized
     69    int64_t packet_time_delta_us = packet_time_us - last_packet_time_us_;
     70    int64_t system_time_delta_us = system_time_us - last_system_time_us_;
     71    int64_t safe_time_delta_us = safe_time_us - last_safe_time_us_;
     72 
     73    // Repair backwards clock resets during initial stall. In this case, the
     74    // reset is observed only in packet time but never in system time.
     75    if (system_time_delta_us < 0)
     76      total_system_time_passed_us_ += config_.stall_threshold->us();
     77    else
     78      total_system_time_passed_us_ += system_time_delta_us;
     79    if (packet_time_delta_us < 0 &&
     80        total_system_time_passed_us_ < config_.stall_threshold->us()) {
     81      static_clock_offset_us_ -= packet_time_delta_us;
     82    }
     83    corrected_time_us += static_clock_offset_us_;
     84 
     85    // Detect resets inbetween clock readings in socket and app.
     86    bool forward_clock_reset =
     87        corrected_time_us + config_.tolerance->us() < last_corrected_time_us_;
     88    bool obvious_backward_clock_reset = system_time_us < packet_time_us;
     89 
     90    // Harder case with backward clock reset during stall, the reset being
     91    // smaller than the stall. Compensate throughout the stall.
     92    bool small_backward_clock_reset =
     93        !obvious_backward_clock_reset &&
     94        safe_time_delta_us > system_time_delta_us + config_.tolerance->us();
     95    bool stall_start =
     96        packet_time_delta_us >= 0 &&
     97        system_time_delta_us > packet_time_delta_us + config_.tolerance->us();
     98    bool stall_is_over = safe_time_delta_us > config_.stall_threshold->us();
     99    bool packet_time_caught_up =
    100        packet_time_delta_us < 0 && system_time_delta_us >= 0;
    101    if (stall_start && small_backward_clock_reset)
    102      small_reset_during_stall_ = true;
    103    else if (stall_is_over || packet_time_caught_up)
    104      small_reset_during_stall_ = false;
    105 
    106    // If resets are detected, advance time by (capped) packet time increase.
    107    if (forward_clock_reset || obvious_backward_clock_reset ||
    108        small_reset_during_stall_) {
    109      corrected_time_us = last_corrected_time_us_ +
    110                          SafeClamp(packet_time_delta_us, 0,
    111                                    config_.max_packet_time_repair->us());
    112    }
    113  }
    114 
    115  last_corrected_time_us_ = corrected_time_us;
    116  last_packet_time_us_ = packet_time_us;
    117  last_system_time_us_ = system_time_us;
    118  last_safe_time_us_ = safe_time_us;
    119  return corrected_time_us;
    120 }
    121 
    122 }  // namespace webrtc