tor-browser

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

inter_arrival.cc (6637B)


      1 /*
      2 *  Copyright (c) 2013 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 "modules/remote_bitrate_estimator/inter_arrival.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 
     16 #include "modules/include/module_common_types_public.h"
     17 #include "rtc_base/checks.h"
     18 #include "rtc_base/logging.h"
     19 
     20 namespace webrtc {
     21 
     22 static const int kBurstDeltaThresholdMs = 5;
     23 static const int kMaxBurstDurationMs = 100;
     24 
     25 InterArrival::InterArrival(uint32_t timestamp_group_length_ticks,
     26                           double timestamp_to_ms_coeff)
     27    : kTimestampGroupLengthTicks(timestamp_group_length_ticks),
     28      current_timestamp_group_(),
     29      prev_timestamp_group_(),
     30      timestamp_to_ms_coeff_(timestamp_to_ms_coeff),
     31      num_consecutive_reordered_packets_(0) {}
     32 
     33 bool InterArrival::ComputeDeltas(uint32_t timestamp,
     34                                 int64_t arrival_time_ms,
     35                                 int64_t system_time_ms,
     36                                 size_t packet_size,
     37                                 uint32_t* timestamp_delta,
     38                                 int64_t* arrival_time_delta_ms,
     39                                 int* packet_size_delta) {
     40  RTC_DCHECK(timestamp_delta);
     41  RTC_DCHECK(arrival_time_delta_ms);
     42  RTC_DCHECK(packet_size_delta);
     43  bool calculated_deltas = false;
     44  if (current_timestamp_group_.IsFirstPacket()) {
     45    // We don't have enough data to update the filter, so we store it until we
     46    // have two frames of data to process.
     47    current_timestamp_group_.timestamp = timestamp;
     48    current_timestamp_group_.first_timestamp = timestamp;
     49    current_timestamp_group_.first_arrival_ms = arrival_time_ms;
     50  } else if (!PacketInOrder(timestamp)) {
     51    return false;
     52  } else if (NewTimestampGroup(arrival_time_ms, timestamp)) {
     53    // First packet of a later frame, the previous frame sample is ready.
     54    if (prev_timestamp_group_.complete_time_ms >= 0) {
     55      *timestamp_delta =
     56          current_timestamp_group_.timestamp - prev_timestamp_group_.timestamp;
     57      *arrival_time_delta_ms = current_timestamp_group_.complete_time_ms -
     58                               prev_timestamp_group_.complete_time_ms;
     59      // Check system time differences to see if we have an unproportional jump
     60      // in arrival time. In that case reset the inter-arrival computations.
     61      int64_t system_time_delta_ms =
     62          current_timestamp_group_.last_system_time_ms -
     63          prev_timestamp_group_.last_system_time_ms;
     64      if (*arrival_time_delta_ms - system_time_delta_ms >=
     65          kArrivalTimeOffsetThresholdMs) {
     66        RTC_LOG(LS_WARNING)
     67            << "The arrival time clock offset has changed (diff = "
     68            << *arrival_time_delta_ms - system_time_delta_ms
     69            << " ms), resetting.";
     70        Reset();
     71        return false;
     72      }
     73      if (*arrival_time_delta_ms < 0) {
     74        // The group of packets has been reordered since receiving its local
     75        // arrival timestamp.
     76        ++num_consecutive_reordered_packets_;
     77        if (num_consecutive_reordered_packets_ >= kReorderedResetThreshold) {
     78          RTC_LOG(LS_WARNING)
     79              << "Packets are being reordered on the path from the "
     80                 "socket to the bandwidth estimator. Ignoring this "
     81                 "packet for bandwidth estimation, resetting.";
     82          Reset();
     83        }
     84        return false;
     85      } else {
     86        num_consecutive_reordered_packets_ = 0;
     87      }
     88      RTC_DCHECK_GE(*arrival_time_delta_ms, 0);
     89      *packet_size_delta = static_cast<int>(current_timestamp_group_.size) -
     90                           static_cast<int>(prev_timestamp_group_.size);
     91      calculated_deltas = true;
     92    }
     93    prev_timestamp_group_ = current_timestamp_group_;
     94    // The new timestamp is now the current frame.
     95    current_timestamp_group_.first_timestamp = timestamp;
     96    current_timestamp_group_.timestamp = timestamp;
     97    current_timestamp_group_.first_arrival_ms = arrival_time_ms;
     98    current_timestamp_group_.size = 0;
     99  } else {
    100    current_timestamp_group_.timestamp =
    101        LatestTimestamp(current_timestamp_group_.timestamp, timestamp);
    102  }
    103  // Accumulate the frame size.
    104  current_timestamp_group_.size += packet_size;
    105  current_timestamp_group_.complete_time_ms = arrival_time_ms;
    106  current_timestamp_group_.last_system_time_ms = system_time_ms;
    107 
    108  return calculated_deltas;
    109 }
    110 
    111 bool InterArrival::PacketInOrder(uint32_t timestamp) {
    112  if (current_timestamp_group_.IsFirstPacket()) {
    113    return true;
    114  } else {
    115    // Assume that a diff which is bigger than half the timestamp interval
    116    // (32 bits) must be due to reordering. This code is almost identical to
    117    // that in IsNewerTimestamp() in module_common_types.h.
    118    uint32_t timestamp_diff =
    119        timestamp - current_timestamp_group_.first_timestamp;
    120    return timestamp_diff < 0x80000000;
    121  }
    122 }
    123 
    124 // Assumes that `timestamp` is not reordered compared to
    125 // `current_timestamp_group_`.
    126 bool InterArrival::NewTimestampGroup(int64_t arrival_time_ms,
    127                                     uint32_t timestamp) const {
    128  if (current_timestamp_group_.IsFirstPacket()) {
    129    return false;
    130  } else if (BelongsToBurst(arrival_time_ms, timestamp)) {
    131    return false;
    132  } else {
    133    uint32_t timestamp_diff =
    134        timestamp - current_timestamp_group_.first_timestamp;
    135    return timestamp_diff > kTimestampGroupLengthTicks;
    136  }
    137 }
    138 
    139 bool InterArrival::BelongsToBurst(int64_t arrival_time_ms,
    140                                  uint32_t timestamp) const {
    141  RTC_DCHECK_GE(current_timestamp_group_.complete_time_ms, 0);
    142  int64_t arrival_time_delta_ms =
    143      arrival_time_ms - current_timestamp_group_.complete_time_ms;
    144  uint32_t timestamp_diff = timestamp - current_timestamp_group_.timestamp;
    145  int64_t ts_delta_ms = timestamp_to_ms_coeff_ * timestamp_diff + 0.5;
    146  if (ts_delta_ms == 0)
    147    return true;
    148  int propagation_delta_ms = arrival_time_delta_ms - ts_delta_ms;
    149  if (propagation_delta_ms < 0 &&
    150      arrival_time_delta_ms <= kBurstDeltaThresholdMs &&
    151      arrival_time_ms - current_timestamp_group_.first_arrival_ms <
    152          kMaxBurstDurationMs)
    153    return true;
    154  return false;
    155 }
    156 
    157 void InterArrival::Reset() {
    158  num_consecutive_reordered_packets_ = 0;
    159  current_timestamp_group_ = TimestampGroup();
    160  prev_timestamp_group_ = TimestampGroup();
    161 }
    162 }  // namespace webrtc