tor-browser

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

neteq_stats_getter.cc (5999B)


      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 "modules/audio_coding/neteq/tools/neteq_stats_getter.h"
     12 
     13 #include <algorithm>
     14 #include <cstdint>
     15 #include <memory>
     16 #include <numeric>
     17 #include <string>
     18 #include <utility>
     19 
     20 #include "api/audio/audio_frame.h"
     21 #include "api/neteq/neteq.h"
     22 #include "modules/audio_coding/neteq/tools/neteq_delay_analyzer.h"
     23 #include "rtc_base/checks.h"
     24 #include "rtc_base/strings/string_builder.h"
     25 #include "rtc_base/time_utils.h"
     26 
     27 namespace webrtc {
     28 namespace test {
     29 
     30 std::string NetEqStatsGetter::ConcealmentEvent::ToString() const {
     31  char ss_buf[256];
     32  SimpleStringBuilder ss(ss_buf);
     33  ss << "ConcealmentEvent duration_ms:" << duration_ms
     34     << " event_number:" << concealment_event_number
     35     << " time_from_previous_event_end_ms:" << time_from_previous_event_end_ms;
     36  return ss.str();
     37 }
     38 
     39 NetEqStatsGetter::NetEqStatsGetter(
     40    std::unique_ptr<NetEqDelayAnalyzer> delay_analyzer)
     41    : delay_analyzer_(std::move(delay_analyzer)) {}
     42 
     43 void NetEqStatsGetter::BeforeGetAudio(NetEq* neteq) {
     44  if (delay_analyzer_) {
     45    delay_analyzer_->BeforeGetAudio(neteq);
     46  }
     47 }
     48 
     49 void NetEqStatsGetter::AfterGetAudio(int64_t time_now_ms,
     50                                     const AudioFrame& audio_frame,
     51                                     bool muted,
     52                                     NetEq* neteq) {
     53  // TODO(minyue): Get stats should better not be called as a call back after
     54  // get audio. It is called independently from get audio in practice.
     55  const auto lifetime_stat = neteq->GetLifetimeStatistics();
     56  if (last_stats_query_time_ms_ == 0 ||
     57      TimeDiff(time_now_ms, last_stats_query_time_ms_) >=
     58          stats_query_interval_ms_) {
     59    NetEqNetworkStatistics stats;
     60    RTC_CHECK_EQ(neteq->NetworkStatistics(&stats), 0);
     61    stats_.push_back(std::make_pair(time_now_ms, stats));
     62    lifetime_stats_.push_back(std::make_pair(time_now_ms, lifetime_stat));
     63    last_stats_query_time_ms_ = time_now_ms;
     64  }
     65 
     66  const auto voice_concealed_samples =
     67      lifetime_stat.concealed_samples - lifetime_stat.silent_concealed_samples;
     68  if (current_concealment_event_ != lifetime_stat.concealment_events &&
     69      voice_concealed_samples_until_last_event_ < voice_concealed_samples) {
     70    if (last_event_end_time_ms_ > 0) {
     71      // Do not account for the first event to avoid start of the call
     72      // skewing.
     73      ConcealmentEvent concealment_event;
     74      uint64_t last_event_voice_concealed_samples =
     75          voice_concealed_samples - voice_concealed_samples_until_last_event_;
     76      RTC_CHECK_GT(last_event_voice_concealed_samples, 0);
     77      concealment_event.duration_ms = last_event_voice_concealed_samples /
     78                                      (audio_frame.sample_rate_hz_ / 1000);
     79      concealment_event.concealment_event_number = current_concealment_event_;
     80      concealment_event.time_from_previous_event_end_ms =
     81          time_now_ms - last_event_end_time_ms_;
     82      concealment_events_.emplace_back(concealment_event);
     83      voice_concealed_samples_until_last_event_ = voice_concealed_samples;
     84    }
     85    last_event_end_time_ms_ = time_now_ms;
     86    voice_concealed_samples_until_last_event_ = voice_concealed_samples;
     87    current_concealment_event_ = lifetime_stat.concealment_events;
     88  }
     89 
     90  if (delay_analyzer_) {
     91    delay_analyzer_->AfterGetAudio(time_now_ms, audio_frame, muted, neteq);
     92  }
     93 }
     94 
     95 double NetEqStatsGetter::AverageSpeechExpandRate() const {
     96  double sum_speech_expand = std::accumulate(
     97      stats_.begin(), stats_.end(), double{0.0},
     98      [](double a, std::pair<int64_t, NetEqNetworkStatistics> b) {
     99        return a + static_cast<double>(b.second.speech_expand_rate);
    100      });
    101  return sum_speech_expand / 16384.0 / stats_.size();
    102 }
    103 
    104 NetEqStatsGetter::Stats NetEqStatsGetter::AverageStats() const {
    105  Stats sum_stats = std::accumulate(
    106      stats_.begin(), stats_.end(), Stats(),
    107      [](Stats a, std::pair<int64_t, NetEqNetworkStatistics> bb) {
    108        const auto& b = bb.second;
    109        a.current_buffer_size_ms += b.current_buffer_size_ms;
    110        a.preferred_buffer_size_ms += b.preferred_buffer_size_ms;
    111        a.jitter_peaks_found += b.jitter_peaks_found;
    112        a.expand_rate += b.expand_rate / 16384.0;
    113        a.speech_expand_rate += b.speech_expand_rate / 16384.0;
    114        a.preemptive_rate += b.preemptive_rate / 16384.0;
    115        a.accelerate_rate += b.accelerate_rate / 16384.0;
    116        a.secondary_decoded_rate += b.secondary_decoded_rate / 16384.0;
    117        a.secondary_discarded_rate += b.secondary_discarded_rate / 16384.0;
    118        a.mean_waiting_time_ms += b.mean_waiting_time_ms;
    119        a.median_waiting_time_ms += b.median_waiting_time_ms;
    120        a.min_waiting_time_ms = std::min(
    121            a.min_waiting_time_ms, static_cast<double>(b.min_waiting_time_ms));
    122        a.max_waiting_time_ms = std::max(
    123            a.max_waiting_time_ms, static_cast<double>(b.max_waiting_time_ms));
    124        return a;
    125      });
    126 
    127  sum_stats.current_buffer_size_ms /= stats_.size();
    128  sum_stats.preferred_buffer_size_ms /= stats_.size();
    129  sum_stats.jitter_peaks_found /= stats_.size();
    130  sum_stats.packet_loss_rate /= stats_.size();
    131  sum_stats.expand_rate /= stats_.size();
    132  sum_stats.speech_expand_rate /= stats_.size();
    133  sum_stats.preemptive_rate /= stats_.size();
    134  sum_stats.accelerate_rate /= stats_.size();
    135  sum_stats.secondary_decoded_rate /= stats_.size();
    136  sum_stats.secondary_discarded_rate /= stats_.size();
    137  sum_stats.added_zero_samples /= stats_.size();
    138  sum_stats.mean_waiting_time_ms /= stats_.size();
    139  sum_stats.median_waiting_time_ms /= stats_.size();
    140 
    141  return sum_stats;
    142 }
    143 
    144 }  // namespace test
    145 }  // namespace webrtc