blob: 9b82de56ad5ef6410f187ac432797d101502af68 [file] [log] [blame]
Niels Mölleraf175952018-08-13 13:23:08 +02001/*
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/rtp_rtcp/source/contributing_sources.h"
12
13namespace webrtc {
14
15namespace {
16
17// Set by the spec, see
18// https://www.w3.org/TR/webrtc/#dom-rtcrtpreceiver-getcontributingsources
19constexpr int64_t kHistoryMs = 10 * rtc::kNumMillisecsPerSec;
20
21// Allow some stale records to accumulate before cleaning.
22constexpr int64_t kPruningIntervalMs = 15 * rtc::kNumMillisecsPerSec;
23
24} // namespace
25
26ContributingSources::ContributingSources() = default;
27ContributingSources::~ContributingSources() = default;
28
29void ContributingSources::Update(int64_t now_ms,
30 rtc::ArrayView<const uint32_t> csrcs) {
31 for (uint32_t csrc : csrcs) {
32 last_seen_ms_[csrc] = now_ms;
33 }
34 if (!next_pruning_ms_) {
35 next_pruning_ms_ = now_ms + kPruningIntervalMs;
36 } else if (now_ms > next_pruning_ms_) {
37 // To prevent unlimited growth, prune it every 15 seconds.
38 DeleteOldEntries(now_ms);
39 }
40}
41
42// Return contributing sources seen the last 10 s.
43// TODO(nisse): It would be more efficient to delete any stale entries while
44// iterating over the mapping, but then we'd have to make the method
45// non-const.
46std::vector<RtpSource> ContributingSources::GetSources(int64_t now_ms) const {
47 std::vector<RtpSource> sources;
48 for (auto& record : last_seen_ms_) {
49 if (record.second >= now_ms - kHistoryMs) {
50 sources.emplace_back(record.second, record.first, RtpSourceType::CSRC);
51 }
52 }
53
54 return sources;
55}
56
57// Delete stale entries.
58void ContributingSources::DeleteOldEntries(int64_t now_ms) {
59 for (auto it = last_seen_ms_.begin(); it != last_seen_ms_.end();) {
60 if (it->second >= now_ms - kHistoryMs) {
61 // Still relevant.
62 ++it;
63 } else {
64 it = last_seen_ms_.erase(it);
65 }
66 }
67 next_pruning_ms_ = now_ms + kPruningIntervalMs;
68}
69
70} // namespace webrtc