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

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

Issue 2997803002: Reduce locking when collecting receive statistics. (Closed)
Patch Set: Undo RtcpReportBlocks() optimization 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
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 NotifyRtpCallback(UpdateCounters(header, packet_length, retransmitted));
60 NotifyRtpCallback();
61 } 61 }
62 62
63 void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header, 63 StreamDataCounters StreamStatisticianImpl::UpdateCounters(
64 size_t packet_length, 64 const RTPHeader& header,
65 bool retransmitted) { 65 size_t packet_length,
66 bool retransmitted) {
66 rtc::CritScope cs(&stream_lock_); 67 rtc::CritScope cs(&stream_lock_);
67 bool in_order = InOrderPacketInternal(header.sequenceNumber); 68 bool in_order = InOrderPacketInternal(header.sequenceNumber);
68 ssrc_ = header.ssrc; 69 RTC_DCHECK_EQ(ssrc_, header.ssrc);
69 incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds()); 70 incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds());
70 receive_counters_.transmitted.AddPacket(packet_length, header); 71 receive_counters_.transmitted.AddPacket(packet_length, header);
71 if (!in_order && retransmitted) { 72 if (!in_order && retransmitted) {
72 receive_counters_.retransmitted.AddPacket(packet_length, header); 73 receive_counters_.retransmitted.AddPacket(packet_length, header);
73 } 74 }
74 75
75 if (receive_counters_.transmitted.packets == 1) { 76 if (receive_counters_.transmitted.packets == 1) {
76 received_seq_first_ = header.sequenceNumber; 77 received_seq_first_ = header.sequenceNumber;
77 receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds(); 78 receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds();
78 } 79 }
(...skipping 23 matching lines...) Expand all
102 last_received_timestamp_ = header.timestamp; 103 last_received_timestamp_ = header.timestamp;
103 last_receive_time_ntp_ = receive_time; 104 last_receive_time_ntp_ = receive_time;
104 last_receive_time_ms_ = clock_->TimeInMilliseconds(); 105 last_receive_time_ms_ = clock_->TimeInMilliseconds();
105 } 106 }
106 107
107 size_t packet_oh = header.headerLength + header.paddingLength; 108 size_t packet_oh = header.headerLength + header.paddingLength;
108 109
109 // Our measured overhead. Filter from RFC 5104 4.2.1.2: 110 // Our measured overhead. Filter from RFC 5104 4.2.1.2:
110 // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH, 111 // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
111 received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4; 112 received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
113 return receive_counters_;
112 } 114 }
113 115
114 void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header, 116 void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
115 NtpTime receive_time) { 117 NtpTime receive_time) {
116 uint32_t receive_time_rtp = 118 uint32_t receive_time_rtp =
117 NtpToRtp(receive_time, header.payload_type_frequency); 119 NtpToRtp(receive_time, header.payload_type_frequency);
118 uint32_t last_receive_time_rtp = 120 uint32_t last_receive_time_rtp =
119 NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency); 121 NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency);
120 int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) - 122 int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
121 (header.timestamp - last_received_timestamp_); 123 (header.timestamp - last_received_timestamp_);
(...skipping 21 matching lines...) Expand all
143 time_diff_samples_ext = std::abs(time_diff_samples_ext); 145 time_diff_samples_ext = std::abs(time_diff_samples_ext);
144 146
145 if (time_diff_samples_ext < 450000) { 147 if (time_diff_samples_ext < 450000) {
146 int32_t jitter_diffQ4TransmissionTimeOffset = 148 int32_t jitter_diffQ4TransmissionTimeOffset =
147 (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_; 149 (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
148 jitter_q4_transmission_time_offset_ += 150 jitter_q4_transmission_time_offset_ +=
149 ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4); 151 ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
150 } 152 }
151 } 153 }
152 154
153 void StreamStatisticianImpl::NotifyRtpCallback() { 155 void StreamStatisticianImpl::NotifyRtpCallback(
154 StreamDataCounters data; 156 const StreamDataCounters& counters) {
155 uint32_t ssrc; 157 rtp_callback_->DataCountersUpdated(counters, ssrc_);
156 {
157 rtc::CritScope cs(&stream_lock_);
158 data = receive_counters_;
159 ssrc = ssrc_;
160 }
161 rtp_callback_->DataCountersUpdated(data, ssrc);
162 } 158 }
163 159
164 void StreamStatisticianImpl::NotifyRtcpCallback() { 160 void StreamStatisticianImpl::NotifyRtcpCallback(const RtcpStatistics& stats) {
165 RtcpStatistics data; 161 rtcp_callback_->StatisticsUpdated(stats, ssrc_);
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 } 162 }
174 163
175 void StreamStatisticianImpl::FecPacketReceived(const RTPHeader& header, 164 void StreamStatisticianImpl::FecPacketReceived(const RTPHeader& header,
176 size_t packet_length) { 165 size_t packet_length) {
166 StreamDataCounters data;
177 { 167 {
178 rtc::CritScope cs(&stream_lock_); 168 rtc::CritScope cs(&stream_lock_);
179 receive_counters_.fec.AddPacket(packet_length, header); 169 receive_counters_.fec.AddPacket(packet_length, header);
170 data = receive_counters_;
180 } 171 }
181 NotifyRtpCallback(); 172 NotifyRtpCallback(data);
182 } 173 }
183 174
184 void StreamStatisticianImpl::SetMaxReorderingThreshold( 175 void StreamStatisticianImpl::SetMaxReorderingThreshold(
185 int max_reordering_threshold) { 176 int max_reordering_threshold) {
186 rtc::CritScope cs(&stream_lock_); 177 rtc::CritScope cs(&stream_lock_);
187 max_reordering_threshold_ = max_reordering_threshold; 178 max_reordering_threshold_ = max_reordering_threshold;
188 } 179 }
189 180
190 bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics, 181 bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
191 bool reset) { 182 bool reset) {
(...skipping 11 matching lines...) Expand all
203 return false; 194 return false;
204 } 195 }
205 // Just get last report. 196 // Just get last report.
206 *statistics = last_reported_statistics_; 197 *statistics = last_reported_statistics_;
207 return true; 198 return true;
208 } 199 }
209 200
210 *statistics = CalculateRtcpStatistics(); 201 *statistics = CalculateRtcpStatistics();
211 } 202 }
212 203
213 NotifyRtcpCallback(); 204 NotifyRtcpCallback(*statistics);
214 205
215 return true; 206 return true;
216 } 207 }
217 208
218 RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() { 209 RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
219 RtcpStatistics stats; 210 RtcpStatistics stats;
220 211
221 if (last_report_inorder_packets_ == 0) { 212 if (last_report_inorder_packets_ == 0) {
222 // First time we send a report. 213 // First time we send a report.
223 last_report_seq_max_ = received_seq_first_ - 1; 214 last_report_seq_max_ = received_seq_first_ - 1;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header, 386 void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
396 size_t packet_length, 387 size_t packet_length,
397 bool retransmitted) { 388 bool retransmitted) {
398 StreamStatisticianImpl* impl; 389 StreamStatisticianImpl* impl;
399 { 390 {
400 rtc::CritScope cs(&receive_statistics_lock_); 391 rtc::CritScope cs(&receive_statistics_lock_);
401 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc); 392 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
402 if (it != statisticians_.end()) { 393 if (it != statisticians_.end()) {
403 impl = it->second; 394 impl = it->second;
404 } else { 395 } else {
405 impl = new StreamStatisticianImpl(clock_, this, this); 396 impl = new StreamStatisticianImpl(header.ssrc, clock_, this, this);
406 statisticians_[header.ssrc] = impl; 397 statisticians_[header.ssrc] = impl;
407 } 398 }
408 } 399 }
409 // StreamStatisticianImpl instance is created once and only destroyed when 400 // StreamStatisticianImpl instance is created once and only destroyed when
410 // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has 401 // this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has
411 // it's own locking so don't hold receive_statistics_lock_ (potential 402 // it's own locking so don't hold receive_statistics_lock_ (potential
412 // deadlock). 403 // deadlock).
413 impl->IncomingPacket(header, packet_length, retransmitted); 404 impl->IncomingPacket(header, packet_length, retransmitted);
414 } 405 }
415 406
416 void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header, 407 void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header,
417 size_t packet_length) { 408 size_t packet_length) {
418 rtc::CritScope cs(&receive_statistics_lock_); 409 StreamStatisticianImpl* impl;
419 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc); 410 {
420 // Ignore FEC if it is the first packet. 411 rtc::CritScope cs(&receive_statistics_lock_);
421 if (it != statisticians_.end()) { 412 StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
422 it->second->FecPacketReceived(header, packet_length); 413 // Ignore FEC if it is the first packet.
414 if (it == statisticians_.end())
415 return;
416 impl = it->second;
423 } 417 }
418 impl->FecPacketReceived(header, packet_length);
424 } 419 }
425 420
426 StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const { 421 StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const {
427 StatisticianMap active_statisticians; 422 StatisticianMap active_statisticians;
428 rtc::CritScope cs(&receive_statistics_lock_); 423 rtc::CritScope cs(&receive_statistics_lock_);
429 for (StatisticianImplMap::const_iterator it = statisticians_.begin(); 424 for (StatisticianImplMap::const_iterator it = statisticians_.begin();
430 it != statisticians_.end(); ++it) { 425 it != statisticians_.end(); ++it) {
431 uint32_t secs; 426 uint32_t secs;
432 uint32_t frac; 427 uint32_t frac;
433 it->second->LastReceiveTimeNtp(&secs, &frac); 428 it->second->LastReceiveTimeNtp(&secs, &frac);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 result.pop_back(); 514 result.pop_back();
520 continue; 515 continue;
521 } 516 }
522 block.SetExtHighestSeqNum(stats.extended_highest_sequence_number); 517 block.SetExtHighestSeqNum(stats.extended_highest_sequence_number);
523 block.SetJitter(stats.jitter); 518 block.SetJitter(stats.jitter);
524 } 519 }
525 return result; 520 return result;
526 } 521 }
527 522
528 } // namespace webrtc 523 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698