Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc

Issue 2997803002: Reduce locking when collecting receive statistics. (Closed)
Patch Set: Remove callback helpers. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 11 matching lines...) Expand all
22 #include "webrtc/system_wrappers/include/clock.h" 22 #include "webrtc/system_wrappers/include/clock.h"
23 23
24 namespace webrtc { 24 namespace webrtc {
25 25
26 const int64_t kStatisticsTimeoutMs = 8000; 26 const int64_t kStatisticsTimeoutMs = 8000;
27 const int64_t kStatisticsProcessIntervalMs = 1000; 27 const int64_t kStatisticsProcessIntervalMs = 1000;
28 28
29 StreamStatistician::~StreamStatistician() {} 29 StreamStatistician::~StreamStatistician() {}
30 30
31 StreamStatisticianImpl::StreamStatisticianImpl( 31 StreamStatisticianImpl::StreamStatisticianImpl(
32 uint32_t ssrc,
32 Clock* clock, 33 Clock* clock,
33 RtcpStatisticsCallback* rtcp_callback, 34 RtcpStatisticsCallback* rtcp_callback,
34 StreamDataCountersCallback* rtp_callback) 35 StreamDataCountersCallback* rtp_callback)
35 : clock_(clock), 36 : ssrc_(ssrc),
37 clock_(clock),
36 incoming_bitrate_(kStatisticsProcessIntervalMs, 38 incoming_bitrate_(kStatisticsProcessIntervalMs,
37 RateStatistics::kBpsScale), 39 RateStatistics::kBpsScale),
38 ssrc_(0),
39 max_reordering_threshold_(kDefaultMaxReorderingThreshold), 40 max_reordering_threshold_(kDefaultMaxReorderingThreshold),
40 jitter_q4_(0), 41 jitter_q4_(0),
41 cumulative_loss_(0), 42 cumulative_loss_(0),
42 jitter_q4_transmission_time_offset_(0), 43 jitter_q4_transmission_time_offset_(0),
43 last_receive_time_ms_(0), 44 last_receive_time_ms_(0),
44 last_received_timestamp_(0), 45 last_received_timestamp_(0),
45 last_received_transmission_time_offset_(0), 46 last_received_transmission_time_offset_(0),
46 received_seq_first_(0), 47 received_seq_first_(0),
47 received_seq_max_(0), 48 received_seq_max_(0),
48 received_seq_wraps_(0), 49 received_seq_wraps_(0),
49 received_packet_overhead_(12), 50 received_packet_overhead_(12),
50 last_report_inorder_packets_(0), 51 last_report_inorder_packets_(0),
51 last_report_old_packets_(0), 52 last_report_old_packets_(0),
52 last_report_seq_max_(0), 53 last_report_seq_max_(0),
53 rtcp_callback_(rtcp_callback), 54 rtcp_callback_(rtcp_callback),
54 rtp_callback_(rtp_callback) {} 55 rtp_callback_(rtp_callback) {}
55 56
56 void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header, 57 void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
57 size_t packet_length, 58 size_t packet_length,
58 bool retransmitted) { 59 bool retransmitted) {
59 UpdateCounters(header, packet_length, retransmitted); 60 auto counters = UpdateCounters(header, packet_length, retransmitted);
60 NotifyRtpCallback(); 61 rtp_callback_->DataCountersUpdated(counters, ssrc_);
61 } 62 }
62 63
63 void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header, 64 StreamDataCounters StreamStatisticianImpl::UpdateCounters(
64 size_t packet_length, 65 const RTPHeader& header,
65 bool retransmitted) { 66 size_t packet_length,
67 bool retransmitted) {
66 rtc::CritScope cs(&stream_lock_); 68 rtc::CritScope cs(&stream_lock_);
67 bool in_order = InOrderPacketInternal(header.sequenceNumber); 69 bool in_order = InOrderPacketInternal(header.sequenceNumber);
68 ssrc_ = header.ssrc; 70 RTC_DCHECK_EQ(ssrc_, header.ssrc);
69 incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds()); 71 incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds());
70 receive_counters_.transmitted.AddPacket(packet_length, header); 72 receive_counters_.transmitted.AddPacket(packet_length, header);
71 if (!in_order && retransmitted) { 73 if (!in_order && retransmitted) {
72 receive_counters_.retransmitted.AddPacket(packet_length, header); 74 receive_counters_.retransmitted.AddPacket(packet_length, header);
73 } 75 }
74 76
75 if (receive_counters_.transmitted.packets == 1) { 77 if (receive_counters_.transmitted.packets == 1) {
76 received_seq_first_ = header.sequenceNumber; 78 received_seq_first_ = header.sequenceNumber;
77 receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds(); 79 receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds();
78 } 80 }
(...skipping 23 matching lines...) Expand all
102 last_received_timestamp_ = header.timestamp; 104 last_received_timestamp_ = header.timestamp;
103 last_receive_time_ntp_ = receive_time; 105 last_receive_time_ntp_ = receive_time;
104 last_receive_time_ms_ = clock_->TimeInMilliseconds(); 106 last_receive_time_ms_ = clock_->TimeInMilliseconds();
105 } 107 }
106 108
107 size_t packet_oh = header.headerLength + header.paddingLength; 109 size_t packet_oh = header.headerLength + header.paddingLength;
108 110
109 // Our measured overhead. Filter from RFC 5104 4.2.1.2: 111 // Our measured overhead. Filter from RFC 5104 4.2.1.2:
110 // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH, 112 // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
111 received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4; 113 received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
114 return receive_counters_;
112 } 115 }
113 116
114 void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header, 117 void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
115 NtpTime receive_time) { 118 NtpTime receive_time) {
116 uint32_t receive_time_rtp = 119 uint32_t receive_time_rtp =
117 NtpToRtp(receive_time, header.payload_type_frequency); 120 NtpToRtp(receive_time, header.payload_type_frequency);
118 uint32_t last_receive_time_rtp = 121 uint32_t last_receive_time_rtp =
119 NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency); 122 NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency);
120 int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) - 123 int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
121 (header.timestamp - last_received_timestamp_); 124 (header.timestamp - last_received_timestamp_);
(...skipping 21 matching lines...) Expand all
143 time_diff_samples_ext = std::abs(time_diff_samples_ext); 146 time_diff_samples_ext = std::abs(time_diff_samples_ext);
144 147
145 if (time_diff_samples_ext < 450000) { 148 if (time_diff_samples_ext < 450000) {
146 int32_t jitter_diffQ4TransmissionTimeOffset = 149 int32_t jitter_diffQ4TransmissionTimeOffset =
147 (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_; 150 (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
148 jitter_q4_transmission_time_offset_ += 151 jitter_q4_transmission_time_offset_ +=
149 ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4); 152 ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
150 } 153 }
151 } 154 }
152 155
153 void StreamStatisticianImpl::NotifyRtpCallback() {
154 StreamDataCounters data;
155 uint32_t ssrc;
156 {
157 rtc::CritScope cs(&stream_lock_);
158 data = receive_counters_;
159 ssrc = ssrc_;
160 }
161 rtp_callback_->DataCountersUpdated(data, ssrc);
162 }
163
164 void StreamStatisticianImpl::NotifyRtcpCallback() {
165 RtcpStatistics data;
166 uint32_t ssrc;
167 {
168 rtc::CritScope cs(&stream_lock_);
169 data = last_reported_statistics_;
170 ssrc = ssrc_;
171 }
172 rtcp_callback_->StatisticsUpdated(data, ssrc);
173 }
174
175 void StreamStatisticianImpl::FecPacketReceived(const RTPHeader& header, 156 void StreamStatisticianImpl::FecPacketReceived(const RTPHeader& header,
176 size_t packet_length) { 157 size_t packet_length) {
158 StreamDataCounters counters;
177 { 159 {
178 rtc::CritScope cs(&stream_lock_); 160 rtc::CritScope cs(&stream_lock_);
179 receive_counters_.fec.AddPacket(packet_length, header); 161 receive_counters_.fec.AddPacket(packet_length, header);
162 counters = receive_counters_;
180 } 163 }
181 NotifyRtpCallback(); 164 rtp_callback_->DataCountersUpdated(counters, ssrc_);
182 } 165 }
183 166
184 void StreamStatisticianImpl::SetMaxReorderingThreshold( 167 void StreamStatisticianImpl::SetMaxReorderingThreshold(
185 int max_reordering_threshold) { 168 int max_reordering_threshold) {
186 rtc::CritScope cs(&stream_lock_); 169 rtc::CritScope cs(&stream_lock_);
187 max_reordering_threshold_ = max_reordering_threshold; 170 max_reordering_threshold_ = max_reordering_threshold;
188 } 171 }
189 172
190 bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics, 173 bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
191 bool reset) { 174 bool reset) {
(...skipping 11 matching lines...) Expand all
203 return false; 186 return false;
204 } 187 }
205 // Just get last report. 188 // Just get last report.
206 *statistics = last_reported_statistics_; 189 *statistics = last_reported_statistics_;
207 return true; 190 return true;
208 } 191 }
209 192
210 *statistics = CalculateRtcpStatistics(); 193 *statistics = CalculateRtcpStatistics();
211 } 194 }
212 195
213 NotifyRtcpCallback(); 196 rtcp_callback_->StatisticsUpdated(*statistics, ssrc_);
214
215 return true; 197 return true;
216 } 198 }
217 199
218 RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() { 200 RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
219 RtcpStatistics stats; 201 RtcpStatistics stats;
220 202
221 if (last_report_inorder_packets_ == 0) { 203 if (last_report_inorder_packets_ == 0) {
222 // First time we send a report. 204 // First time we send a report.
223 last_report_seq_max_ = received_seq_first_ - 1; 205 last_report_seq_max_ = received_seq_first_ - 1;
224 } 206 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header, 377 void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
396 size_t packet_length, 378 size_t packet_length,
397 bool retransmitted) { 379 bool retransmitted) {
398 StreamStatisticianImpl* impl; 380 StreamStatisticianImpl* impl;
399 { 381 {
400 rtc::CritScope cs(&receive_statistics_lock_); 382 rtc::CritScope cs(&receive_statistics_lock_);
401 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc); 383 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
402 if (it != statisticians_.end()) { 384 if (it != statisticians_.end()) {
403 impl = it->second; 385 impl = it->second;
404 } else { 386 } else {
405 impl = new StreamStatisticianImpl(clock_, this, this); 387 impl = new StreamStatisticianImpl(header.ssrc, clock_, this, this);
406 statisticians_[header.ssrc] = impl; 388 statisticians_[header.ssrc] = impl;
407 } 389 }
408 } 390 }
409 // StreamStatisticianImpl instance is created once and only destroyed when 391 // StreamStatisticianImpl instance is created once and only destroyed when
410 // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has 392 // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has
411 // it's own locking so don't hold receive_statistics_lock_ (potential 393 // it's own locking so don't hold receive_statistics_lock_ (potential
412 // deadlock). 394 // deadlock).
413 impl->IncomingPacket(header, packet_length, retransmitted); 395 impl->IncomingPacket(header, packet_length, retransmitted);
414 } 396 }
415 397
416 void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header, 398 void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header,
417 size_t packet_length) { 399 size_t packet_length) {
418 rtc::CritScope cs(&receive_statistics_lock_); 400 StreamStatisticianImpl* impl;
419 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc); 401 {
420 // Ignore FEC if it is the first packet. 402 rtc::CritScope cs(&receive_statistics_lock_);
421 if (it != statisticians_.end()) { 403 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
422 it->second->FecPacketReceived(header, packet_length); 404 // Ignore FEC if it is the first packet.
405 if (it == statisticians_.end())
406 return;
407 impl = it->second;
423 } 408 }
409 impl->FecPacketReceived(header, packet_length);
424 } 410 }
425 411
426 StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const { 412 StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const {
427 StatisticianMap active_statisticians; 413 StatisticianMap active_statisticians;
428 rtc::CritScope cs(&receive_statistics_lock_); 414 rtc::CritScope cs(&receive_statistics_lock_);
429 for (StatisticianImplMap::const_iterator it = statisticians_.begin(); 415 for (StatisticianImplMap::const_iterator it = statisticians_.begin();
430 it != statisticians_.end(); ++it) { 416 it != statisticians_.end(); ++it) {
431 uint32_t secs; 417 uint32_t secs;
432 uint32_t frac; 418 uint32_t frac;
433 it->second->LastReceiveTimeNtp(&secs, &frac); 419 it->second->LastReceiveTimeNtp(&secs, &frac);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 result.pop_back(); 505 result.pop_back();
520 continue; 506 continue;
521 } 507 }
522 block.SetExtHighestSeqNum(stats.extended_highest_sequence_number); 508 block.SetExtHighestSeqNum(stats.extended_highest_sequence_number);
523 block.SetJitter(stats.jitter); 509 block.SetJitter(stats.jitter);
524 } 510 }
525 return result; 511 return result;
526 } 512 }
527 513
528 } // namespace webrtc 514 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698