tor-browser

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

packet_arrival_history.cc (4329B)


      1 /*
      2 *  Copyright (c) 2022 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/audio_coding/neteq/packet_arrival_history.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 
     16 #include "api/neteq/tick_timer.h"
     17 #include "rtc_base/checks.h"
     18 
     19 namespace webrtc {
     20 
     21 PacketArrivalHistory::PacketArrivalHistory(const TickTimer* tick_timer,
     22                                           int window_size_ms)
     23    : tick_timer_(tick_timer), window_size_ms_(window_size_ms) {}
     24 
     25 bool PacketArrivalHistory::Insert(uint32_t rtp_timestamp,
     26                                  int packet_length_samples) {
     27  int64_t arrival_timestamp =
     28      tick_timer_->ticks() * tick_timer_->ms_per_tick() * sample_rate_khz_;
     29  PacketArrival packet(timestamp_unwrapper_.Unwrap(rtp_timestamp),
     30                       arrival_timestamp, packet_length_samples);
     31  if (IsObsolete(packet)) {
     32    return false;
     33  }
     34  if (Contains(packet)) {
     35    return false;
     36  }
     37  history_.emplace(packet.rtp_timestamp, packet);
     38  if (packet != history_.rbegin()->second) {
     39    // Packet was reordered.
     40    return true;
     41  }
     42  // Remove old packets.
     43  while (IsObsolete(history_.begin()->second)) {
     44    if (history_.begin()->second == min_packet_arrivals_.front()) {
     45      min_packet_arrivals_.pop_front();
     46    }
     47    if (history_.begin()->second == max_packet_arrivals_.front()) {
     48      max_packet_arrivals_.pop_front();
     49    }
     50    history_.erase(history_.begin());
     51  }
     52  // Ensure ordering constraints.
     53  while (!min_packet_arrivals_.empty() &&
     54         packet <= min_packet_arrivals_.back()) {
     55    min_packet_arrivals_.pop_back();
     56  }
     57  while (!max_packet_arrivals_.empty() &&
     58         packet >= max_packet_arrivals_.back()) {
     59    max_packet_arrivals_.pop_back();
     60  }
     61  min_packet_arrivals_.push_back(packet);
     62  max_packet_arrivals_.push_back(packet);
     63  return true;
     64 }
     65 
     66 void PacketArrivalHistory::Reset() {
     67  history_.clear();
     68  min_packet_arrivals_.clear();
     69  max_packet_arrivals_.clear();
     70  timestamp_unwrapper_.Reset();
     71 }
     72 
     73 int PacketArrivalHistory::GetDelayMs(uint32_t rtp_timestamp) const {
     74  int64_t unwrapped_rtp_timestamp =
     75      timestamp_unwrapper_.PeekUnwrap(rtp_timestamp);
     76  int64_t current_timestamp =
     77      tick_timer_->ticks() * tick_timer_->ms_per_tick() * sample_rate_khz_;
     78  PacketArrival packet(unwrapped_rtp_timestamp, current_timestamp,
     79                       /*duration_ms=*/0);
     80  return GetPacketArrivalDelayMs(packet);
     81 }
     82 
     83 int PacketArrivalHistory::GetMaxDelayMs() const {
     84  if (max_packet_arrivals_.empty()) {
     85    return 0;
     86  }
     87  return GetPacketArrivalDelayMs(max_packet_arrivals_.front());
     88 }
     89 
     90 bool PacketArrivalHistory::IsNewestRtpTimestamp(uint32_t rtp_timestamp) const {
     91  if (history_.empty()) {
     92    return true;
     93  }
     94  int64_t unwrapped_rtp_timestamp =
     95      timestamp_unwrapper_.PeekUnwrap(rtp_timestamp);
     96  return unwrapped_rtp_timestamp == history_.rbegin()->second.rtp_timestamp;
     97 }
     98 
     99 int PacketArrivalHistory::GetPacketArrivalDelayMs(
    100    const PacketArrival& packet_arrival) const {
    101  if (min_packet_arrivals_.empty()) {
    102    return 0;
    103  }
    104  RTC_DCHECK_NE(sample_rate_khz_, 0);
    105  // TODO(jakobi): Timestamps are first converted to millis for bit-exactness.
    106  return std::max<int>(
    107      packet_arrival.arrival_timestamp / sample_rate_khz_ -
    108          min_packet_arrivals_.front().arrival_timestamp / sample_rate_khz_ -
    109          (packet_arrival.rtp_timestamp / sample_rate_khz_ -
    110           min_packet_arrivals_.front().rtp_timestamp / sample_rate_khz_),
    111      0);
    112 }
    113 
    114 bool PacketArrivalHistory::IsObsolete(
    115    const PacketArrival& packet_arrival) const {
    116  if (history_.empty()) {
    117    return false;
    118  }
    119  return packet_arrival.rtp_timestamp + window_size_ms_ * sample_rate_khz_ <
    120         history_.rbegin()->second.rtp_timestamp;
    121 }
    122 
    123 bool PacketArrivalHistory::Contains(const PacketArrival& packet_arrival) const {
    124  auto it = history_.upper_bound(packet_arrival.rtp_timestamp);
    125  if (it == history_.begin()) {
    126    return false;
    127  }
    128  --it;
    129  return it->second.contains(packet_arrival);
    130 }
    131 
    132 }  // namespace webrtc