OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 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 "webrtc/modules/rtp_rtcp/source/bitrate.h" | |
12 | |
13 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | |
14 | |
15 namespace webrtc { | |
16 | |
17 Bitrate::Bitrate(Clock* clock, Observer* observer) | |
18 : clock_(clock), | |
19 packet_rate_(0), | |
20 bitrate_(0), | |
21 bitrate_next_idx_(0), | |
22 time_last_rate_update_(0), | |
23 bytes_count_(0), | |
24 packet_count_(0), | |
25 observer_(observer) { | |
26 memset(packet_rate_array_, 0, sizeof(packet_rate_array_)); | |
27 memset(bitrate_diff_ms_, 0, sizeof(bitrate_diff_ms_)); | |
28 memset(bitrate_array_, 0, sizeof(bitrate_array_)); | |
29 } | |
30 | |
31 Bitrate::~Bitrate() {} | |
32 | |
33 void Bitrate::Update(const size_t bytes) { | |
34 rtc::CritScope cs(&crit_); | |
35 bytes_count_ += bytes; | |
36 packet_count_++; | |
37 } | |
38 | |
39 uint32_t Bitrate::PacketRate() const { | |
40 rtc::CritScope cs(&crit_); | |
41 return packet_rate_; | |
42 } | |
43 | |
44 uint32_t Bitrate::BitrateLast() const { | |
45 rtc::CritScope cs(&crit_); | |
46 return bitrate_; | |
47 } | |
48 | |
49 uint32_t Bitrate::BitrateNow() const { | |
50 rtc::CritScope cs(&crit_); | |
51 int64_t now = clock_->TimeInMilliseconds(); | |
52 int64_t diff_ms = now - time_last_rate_update_; | |
53 | |
54 if (diff_ms > 10000) { // 10 seconds. | |
55 // Too high difference, ignore. | |
56 return bitrate_; | |
57 } | |
58 int64_t bits_since_last_rate_update = 8 * bytes_count_ * 1000; | |
59 | |
60 // We have to consider the time when the measurement was done: | |
61 // ((bits/sec * sec) + (bits)) / sec. | |
62 int64_t bitrate = (static_cast<uint64_t>(bitrate_) * 1000 + | |
63 bits_since_last_rate_update) / (1000 + diff_ms); | |
64 return static_cast<uint32_t>(bitrate); | |
65 } | |
66 | |
67 int64_t Bitrate::time_last_rate_update() const { | |
68 rtc::CritScope cs(&crit_); | |
69 return time_last_rate_update_; | |
70 } | |
71 | |
72 // Triggered by timer. | |
73 void Bitrate::Process() { | |
74 BitrateStatistics stats; | |
75 { | |
76 rtc::CritScope cs(&crit_); | |
77 int64_t now = clock_->CurrentNtpInMilliseconds(); | |
78 int64_t diff_ms = now - time_last_rate_update_; | |
79 | |
80 if (diff_ms < 100) { | |
81 // Not enough data, wait... | |
82 return; | |
83 } | |
84 if (diff_ms > 10000) { // 10 seconds. | |
85 // Too high difference, ignore. | |
86 time_last_rate_update_ = now; | |
87 bytes_count_ = 0; | |
88 packet_count_ = 0; | |
89 return; | |
90 } | |
91 packet_rate_array_[bitrate_next_idx_] = (packet_count_ * 1000) / diff_ms; | |
92 bitrate_array_[bitrate_next_idx_] = 8 * ((bytes_count_ * 1000) / diff_ms); | |
93 bitrate_diff_ms_[bitrate_next_idx_] = diff_ms; | |
94 bitrate_next_idx_++; | |
95 if (bitrate_next_idx_ >= 10) { | |
96 bitrate_next_idx_ = 0; | |
97 } | |
98 int64_t sum_diffMS = 0; | |
99 int64_t sum_bitrateMS = 0; | |
100 int64_t sum_packetrateMS = 0; | |
101 for (int i = 0; i < 10; i++) { | |
102 sum_diffMS += bitrate_diff_ms_[i]; | |
103 sum_bitrateMS += bitrate_array_[i] * bitrate_diff_ms_[i]; | |
104 sum_packetrateMS += packet_rate_array_[i] * bitrate_diff_ms_[i]; | |
105 } | |
106 time_last_rate_update_ = now; | |
107 bytes_count_ = 0; | |
108 packet_count_ = 0; | |
109 packet_rate_ = static_cast<uint32_t>(sum_packetrateMS / sum_diffMS); | |
110 bitrate_ = static_cast<uint32_t>(sum_bitrateMS / sum_diffMS); | |
111 | |
112 stats.bitrate_bps = bitrate_; | |
113 stats.packet_rate = packet_rate_; | |
114 stats.timestamp_ms = now; | |
115 } | |
116 | |
117 if (observer_) | |
118 observer_->BitrateUpdated(stats); | |
119 } | |
120 | |
121 } // namespace webrtc | |
OLD | NEW |