1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
27374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13151f6f2b95bc99093ecaf0d41e1843f0c0c1a547henrike@webrtc.org#include <assert.h>
14151f6f2b95bc99093ecaf0d41e1843f0c0c1a547henrike@webrtc.org
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orgRateStatistics::RateStatistics(uint32_t window_size_ms, float scale)
187374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org    : num_buckets_(window_size_ms + 1),  // N ms in (N+1) buckets.
1966fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      buckets_(new uint32_t[num_buckets_]()),
207374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org      accumulated_count_(0),
2166fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      oldest_time_(0),
2266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      oldest_index_(0),
237374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org      scale_(scale / (num_buckets_ - 1)) {
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
267374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orgRateStatistics::~RateStatistics() {
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
297374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orgvoid RateStatistics::Reset() {
307374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org  accumulated_count_ = 0;
3166fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  oldest_time_ = 0;
3266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  oldest_index_ = 0;
3366fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  for (int i = 0; i < num_buckets_; i++) {
3466fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    buckets_[i] = 0;
35e5117e74a235e505464e8fdd816940e6334e7633solenberg@webrtc.org  }
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
387374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orgvoid RateStatistics::Update(uint32_t count, int64_t now_ms) {
3966fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  if (now_ms < oldest_time_) {
4066fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    // Too old data is ignored.
4166fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    return;
4266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  }
4366fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org
4466fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  EraseOld(now_ms);
4566fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org
4666fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  int now_offset = static_cast<int>(now_ms - oldest_time_);
4766fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  assert(now_offset < num_buckets_);
4866fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  int index = oldest_index_ + now_offset;
4966fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  if (index >= num_buckets_) {
5066fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    index -= num_buckets_;
5166fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  }
527374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org  buckets_[index] += count;
537374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org  accumulated_count_ += count;
5466fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org}
5566fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org
567374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orguint32_t RateStatistics::Rate(int64_t now_ms) {
57e5117e74a235e505464e8fdd816940e6334e7633solenberg@webrtc.org  EraseOld(now_ms);
587374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org  return static_cast<uint32_t>(accumulated_count_ * scale_ + 0.5f);
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
617374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.orgvoid RateStatistics::EraseOld(int64_t now_ms) {
6266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  int64_t new_oldest_time = now_ms - num_buckets_ + 1;
6366fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  if (new_oldest_time <= oldest_time_) {
6466fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    return;
6566fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  }
6666fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org
6766fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  while (oldest_time_ < new_oldest_time) {
687374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org    uint32_t count_in_oldest_bucket = buckets_[oldest_index_];
697374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org    assert(accumulated_count_ >= count_in_oldest_bucket);
707374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org    accumulated_count_ -= count_in_oldest_bucket;
7166fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    buckets_[oldest_index_] = 0;
7266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    if (++oldest_index_ >= num_buckets_) {
7366fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      oldest_index_ = 0;
7466fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    }
7566fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org    ++oldest_time_;
767374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org    if (accumulated_count_ == 0) {
7766fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      // This guarantees we go through all the buckets at most once, even if
7866fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org      // |new_oldest_time| is far greater than |oldest_time_|.
79e5117e74a235e505464e8fdd816940e6334e7633solenberg@webrtc.org      break;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
81e5117e74a235e505464e8fdd816940e6334e7633solenberg@webrtc.org  }
8266fba2bd7509f4b4f1689abbeeef034bbd809ce3mikhal@webrtc.org  oldest_time_ = new_oldest_time;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
847374da3865411d9b58de7210d66cfa60237580edsprang@webrtc.org
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
86