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

Side by Side Diff: webrtc/call/call.cc

Issue 1440603002: Add receive bitrate UMA stats. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: . Created 5 years, 1 month 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 | « no previous file | webrtc/video/end_to_end_tests.cc » ('j') | 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 15 matching lines...) Expand all
26 #include "webrtc/call/congestion_controller.h" 26 #include "webrtc/call/congestion_controller.h"
27 #include "webrtc/call/rtc_event_log.h" 27 #include "webrtc/call/rtc_event_log.h"
28 #include "webrtc/common.h" 28 #include "webrtc/common.h"
29 #include "webrtc/config.h" 29 #include "webrtc/config.h"
30 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" 30 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
31 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 31 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
32 #include "webrtc/modules/utility/include/process_thread.h" 32 #include "webrtc/modules/utility/include/process_thread.h"
33 #include "webrtc/system_wrappers/include/cpu_info.h" 33 #include "webrtc/system_wrappers/include/cpu_info.h"
34 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 34 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
35 #include "webrtc/system_wrappers/include/logging.h" 35 #include "webrtc/system_wrappers/include/logging.h"
36 #include "webrtc/system_wrappers/include/metrics.h"
36 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" 37 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
37 #include "webrtc/system_wrappers/include/trace.h" 38 #include "webrtc/system_wrappers/include/trace.h"
38 #include "webrtc/video/video_receive_stream.h" 39 #include "webrtc/video/video_receive_stream.h"
39 #include "webrtc/video/video_send_stream.h" 40 #include "webrtc/video/video_send_stream.h"
40 #include "webrtc/video_engine/call_stats.h" 41 #include "webrtc/video_engine/call_stats.h"
41 #include "webrtc/voice_engine/include/voe_codec.h" 42 #include "webrtc/voice_engine/include/voe_codec.h"
42 43
43 namespace webrtc { 44 namespace webrtc {
44 45
45 const int Call::Config::kDefaultStartBitrateBps = 300000; 46 const int Call::Config::kDefaultStartBitrateBps = 300000;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 99
99 VoiceEngine* voice_engine() { 100 VoiceEngine* voice_engine() {
100 internal::AudioState* audio_state = 101 internal::AudioState* audio_state =
101 static_cast<internal::AudioState*>(config_.audio_state.get()); 102 static_cast<internal::AudioState*>(config_.audio_state.get());
102 if (audio_state) 103 if (audio_state)
103 return audio_state->voice_engine(); 104 return audio_state->voice_engine();
104 else 105 else
105 return nullptr; 106 return nullptr;
106 } 107 }
107 108
109 void UpdateHistograms();
110
111 const Clock* const clock_;
112
108 const int num_cpu_cores_; 113 const int num_cpu_cores_;
109 const rtc::scoped_ptr<ProcessThread> module_process_thread_; 114 const rtc::scoped_ptr<ProcessThread> module_process_thread_;
110 const rtc::scoped_ptr<CallStats> call_stats_; 115 const rtc::scoped_ptr<CallStats> call_stats_;
111 const rtc::scoped_ptr<CongestionController> congestion_controller_; 116 const rtc::scoped_ptr<CongestionController> congestion_controller_;
112 Call::Config config_; 117 Call::Config config_;
113 rtc::ThreadChecker configuration_thread_checker_; 118 rtc::ThreadChecker configuration_thread_checker_;
114 119
115 bool network_enabled_; 120 bool network_enabled_;
116 121
117 rtc::scoped_ptr<RWLockWrapper> receive_crit_; 122 rtc::scoped_ptr<RWLockWrapper> receive_crit_;
(...skipping 10 matching lines...) Expand all
128 rtc::scoped_ptr<RWLockWrapper> send_crit_; 133 rtc::scoped_ptr<RWLockWrapper> send_crit_;
129 // Audio and Video send streams are owned by the client that creates them. 134 // Audio and Video send streams are owned by the client that creates them.
130 std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_); 135 std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_);
131 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); 136 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_);
132 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); 137 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_);
133 138
134 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; 139 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_;
135 140
136 RtcEventLog* event_log_ = nullptr; 141 RtcEventLog* event_log_ = nullptr;
137 142
143 size_t received_video_bytes_;
pbos-webrtc 2015/11/11 14:56:57 Can you put notes on how these are synchronized?
stefan-webrtc 2015/11/11 15:49:25 Done.
144 size_t received_audio_bytes_;
145 size_t received_rtcp_bytes_;
146 int64_t first_rtp_received_ms_;
147 int64_t first_rtcp_received_ms_;
148
138 RTC_DISALLOW_COPY_AND_ASSIGN(Call); 149 RTC_DISALLOW_COPY_AND_ASSIGN(Call);
139 }; 150 };
140 } // namespace internal 151 } // namespace internal
141 152
142 Call* Call::Create(const Call::Config& config) { 153 Call* Call::Create(const Call::Config& config) {
143 return new internal::Call(config); 154 return new internal::Call(config);
144 } 155 }
145 156
146 namespace internal { 157 namespace internal {
147 158
148 Call::Call(const Call::Config& config) 159 Call::Call(const Call::Config& config)
149 : num_cpu_cores_(CpuInfo::DetectNumberOfCores()), 160 : clock_(Clock::GetRealTimeClock()),
161 num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
150 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), 162 module_process_thread_(ProcessThread::Create("ModuleProcessThread")),
151 call_stats_(new CallStats()), 163 call_stats_(new CallStats()),
152 congestion_controller_(new CongestionController( 164 congestion_controller_(
153 module_process_thread_.get(), call_stats_.get())), 165 new CongestionController(module_process_thread_.get(),
166 call_stats_.get())),
154 config_(config), 167 config_(config),
155 network_enabled_(true), 168 network_enabled_(true),
156 receive_crit_(RWLockWrapper::CreateRWLock()), 169 receive_crit_(RWLockWrapper::CreateRWLock()),
157 send_crit_(RWLockWrapper::CreateRWLock()) { 170 send_crit_(RWLockWrapper::CreateRWLock()),
171 received_video_bytes_(0),
172 received_audio_bytes_(0),
173 received_rtcp_bytes_(0),
174 first_rtp_received_ms_(-1),
175 first_rtcp_received_ms_(-1) {
158 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); 176 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0);
159 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, 177 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps,
160 config.bitrate_config.min_bitrate_bps); 178 config.bitrate_config.min_bitrate_bps);
161 if (config.bitrate_config.max_bitrate_bps != -1) { 179 if (config.bitrate_config.max_bitrate_bps != -1) {
162 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, 180 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps,
163 config.bitrate_config.start_bitrate_bps); 181 config.bitrate_config.start_bitrate_bps);
164 } 182 }
165 if (config.audio_state.get()) { 183 if (config.audio_state.get()) {
166 ScopedVoEInterface<VoECodec> voe_codec(voice_engine()); 184 ScopedVoEInterface<VoECodec> voe_codec(voice_engine());
167 event_log_ = voe_codec->GetEventLog(); 185 event_log_ = voe_codec->GetEventLog();
168 } 186 }
169 187
170 Trace::CreateTrace(); 188 Trace::CreateTrace();
171 module_process_thread_->Start(); 189 module_process_thread_->Start();
172 module_process_thread_->RegisterModule(call_stats_.get()); 190 module_process_thread_->RegisterModule(call_stats_.get());
173 191
174 congestion_controller_->SetBweBitrates( 192 congestion_controller_->SetBweBitrates(
175 config_.bitrate_config.min_bitrate_bps, 193 config_.bitrate_config.min_bitrate_bps,
176 config_.bitrate_config.start_bitrate_bps, 194 config_.bitrate_config.start_bitrate_bps,
177 config_.bitrate_config.max_bitrate_bps); 195 config_.bitrate_config.max_bitrate_bps);
178 196
179 congestion_controller_->GetBitrateController()->SetEventLog(event_log_); 197 congestion_controller_->GetBitrateController()->SetEventLog(event_log_);
180 } 198 }
181 199
182 Call::~Call() { 200 Call::~Call() {
201 UpdateHistograms();
183 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); 202 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
184 RTC_CHECK(audio_send_ssrcs_.empty()); 203 RTC_CHECK(audio_send_ssrcs_.empty());
185 RTC_CHECK(video_send_ssrcs_.empty()); 204 RTC_CHECK(video_send_ssrcs_.empty());
186 RTC_CHECK(video_send_streams_.empty()); 205 RTC_CHECK(video_send_streams_.empty());
187 RTC_CHECK(audio_receive_ssrcs_.empty()); 206 RTC_CHECK(audio_receive_ssrcs_.empty());
188 RTC_CHECK(video_receive_ssrcs_.empty()); 207 RTC_CHECK(video_receive_ssrcs_.empty());
189 RTC_CHECK(video_receive_streams_.empty()); 208 RTC_CHECK(video_receive_streams_.empty());
190 209
191 module_process_thread_->DeRegisterModule(call_stats_.get()); 210 module_process_thread_->DeRegisterModule(call_stats_.get());
192 module_process_thread_->Stop(); 211 module_process_thread_->Stop();
193 Trace::ReturnTrace(); 212 Trace::ReturnTrace();
194 } 213 }
195 214
215 void Call::UpdateHistograms() {
216 int64_t first_packet_received_ms = first_rtp_received_ms_;
217 if (first_rtcp_received_ms_ != -1) {
218 if (first_packet_received_ms != -1) {
219 first_packet_received_ms =
220 std::min(first_packet_received_ms, first_rtcp_received_ms_);
221 } else {
222 first_packet_received_ms = first_rtcp_received_ms_;
223 }
224 }
225 if (first_packet_received_ms == -1)
226 return;
227 int64_t elapsed_sec =
228 (clock_->TimeInMilliseconds() - first_packet_received_ms) / 1000;
229 if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
åsapersson 2015/11/11 15:35:24 maybe early return
stefan-webrtc 2015/11/11 15:59:04 Done.
230 if (received_video_bytes_ > 0) {
231 RTC_HISTOGRAM_COUNTS_100000(
232 "WebRTC.Call.VideoBitrateReceivedInKbps",
233 static_cast<int>(received_video_bytes_ * 8 / elapsed_sec / 1000));
234 }
235 if (received_audio_bytes_ > 0) {
236 RTC_HISTOGRAM_COUNTS_100000(
237 "WebRTC.Call.AudioBitrateReceivedInKbps",
238 static_cast<int>(received_audio_bytes_ * 8 / elapsed_sec / 1000));
239 }
240 if (received_rtcp_bytes_ > 0) {
241 RTC_HISTOGRAM_COUNTS_100000(
242 "WebRTC.Call.RtcpBitrateReceivedInKbps",
243 static_cast<int>(received_rtcp_bytes_ * 8 / elapsed_sec / 1000));
244 }
245 // Only report the total bitrate received if we have been receiving audio or
246 // video packets. This is to avoid getting a huge spike close to zero for
247 // Calls which are only receiving RTCP.
248 if (received_video_bytes_ + received_audio_bytes_ > 0) {
249 RTC_HISTOGRAM_COUNTS_100000(
250 "WebRTC.Call.BitrateReceivedInKbps",
251 static_cast<int>((received_video_bytes_ + received_audio_bytes_ +
252 received_rtcp_bytes_) *
253 8 / elapsed_sec / 1000));
254 }
255 }
256 }
257
196 PacketReceiver* Call::Receiver() { 258 PacketReceiver* Call::Receiver() {
197 // TODO(solenberg): Some test cases in EndToEndTest use this from a different 259 // TODO(solenberg): Some test cases in EndToEndTest use this from a different
198 // thread. Re-enable once that is fixed. 260 // thread. Re-enable once that is fixed.
199 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); 261 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
200 return this; 262 return this;
201 } 263 }
202 264
203 webrtc::AudioSendStream* Call::CreateAudioSendStream( 265 webrtc::AudioSendStream* Call::CreateAudioSendStream(
204 const webrtc::AudioSendStream::Config& config) { 266 const webrtc::AudioSendStream::Config& config) {
205 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); 267 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 } 582 }
521 } 583 }
522 584
523 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, 585 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
524 const uint8_t* packet, 586 const uint8_t* packet,
525 size_t length) { 587 size_t length) {
526 // TODO(pbos): Figure out what channel needs it actually. 588 // TODO(pbos): Figure out what channel needs it actually.
527 // Do NOT broadcast! Also make sure it's a valid packet. 589 // Do NOT broadcast! Also make sure it's a valid packet.
528 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that 590 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that
529 // there's no receiver of the packet. 591 // there's no receiver of the packet.
592 received_rtcp_bytes_ += length;
593 if (first_rtcp_received_ms_ == -1)
594 first_rtcp_received_ms_ = clock_->TimeInMilliseconds();
530 bool rtcp_delivered = false; 595 bool rtcp_delivered = false;
531 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { 596 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
532 ReadLockScoped read_lock(*receive_crit_); 597 ReadLockScoped read_lock(*receive_crit_);
533 for (VideoReceiveStream* stream : video_receive_streams_) { 598 for (VideoReceiveStream* stream : video_receive_streams_) {
534 if (stream->DeliverRtcp(packet, length)) { 599 if (stream->DeliverRtcp(packet, length)) {
535 rtcp_delivered = true; 600 rtcp_delivered = true;
536 if (event_log_) 601 if (event_log_)
537 event_log_->LogRtcpPacket(true, media_type, packet, length); 602 event_log_->LogRtcpPacket(true, media_type, packet, length);
538 } 603 }
539 } 604 }
(...skipping 12 matching lines...) Expand all
552 } 617 }
553 618
554 PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type, 619 PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
555 const uint8_t* packet, 620 const uint8_t* packet,
556 size_t length, 621 size_t length,
557 const PacketTime& packet_time) { 622 const PacketTime& packet_time) {
558 // Minimum RTP header size. 623 // Minimum RTP header size.
559 if (length < 12) 624 if (length < 12)
560 return DELIVERY_PACKET_ERROR; 625 return DELIVERY_PACKET_ERROR;
561 626
627 if (first_rtp_received_ms_ == -1)
628 first_rtp_received_ms_ = clock_->TimeInMilliseconds();
629
562 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]); 630 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]);
563
564 ReadLockScoped read_lock(*receive_crit_); 631 ReadLockScoped read_lock(*receive_crit_);
565 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) { 632 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
633 received_audio_bytes_ += length;
566 auto it = audio_receive_ssrcs_.find(ssrc); 634 auto it = audio_receive_ssrcs_.find(ssrc);
567 if (it != audio_receive_ssrcs_.end()) { 635 if (it != audio_receive_ssrcs_.end()) {
568 auto status = it->second->DeliverRtp(packet, length, packet_time) 636 auto status = it->second->DeliverRtp(packet, length, packet_time)
569 ? DELIVERY_OK 637 ? DELIVERY_OK
570 : DELIVERY_PACKET_ERROR; 638 : DELIVERY_PACKET_ERROR;
571 if (status == DELIVERY_OK && event_log_) 639 if (status == DELIVERY_OK && event_log_)
572 event_log_->LogRtpHeader(true, media_type, packet, length); 640 event_log_->LogRtpHeader(true, media_type, packet, length);
573 return status; 641 return status;
574 } 642 }
575 } 643 }
576 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { 644 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
645 received_video_bytes_ += length;
åsapersson 2015/11/11 15:35:24 Could media type any be counted twice?
stefan-webrtc 2015/11/11 15:59:04 Fixed.
577 auto it = video_receive_ssrcs_.find(ssrc); 646 auto it = video_receive_ssrcs_.find(ssrc);
578 if (it != video_receive_ssrcs_.end()) { 647 if (it != video_receive_ssrcs_.end()) {
579 auto status = it->second->DeliverRtp(packet, length, packet_time) 648 auto status = it->second->DeliverRtp(packet, length, packet_time)
580 ? DELIVERY_OK 649 ? DELIVERY_OK
581 : DELIVERY_PACKET_ERROR; 650 : DELIVERY_PACKET_ERROR;
582 if (status == DELIVERY_OK && event_log_) 651 if (status == DELIVERY_OK && event_log_)
583 event_log_->LogRtpHeader(true, media_type, packet, length); 652 event_log_->LogRtpHeader(true, media_type, packet, length);
584 return status; 653 return status;
585 } 654 }
586 } 655 }
(...skipping 10 matching lines...) Expand all
597 // thread. Then this check can be enabled. 666 // thread. Then this check can be enabled.
598 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); 667 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread());
599 if (RtpHeaderParser::IsRtcp(packet, length)) 668 if (RtpHeaderParser::IsRtcp(packet, length))
600 return DeliverRtcp(media_type, packet, length); 669 return DeliverRtcp(media_type, packet, length);
601 670
602 return DeliverRtp(media_type, packet, length, packet_time); 671 return DeliverRtp(media_type, packet, length, packet_time);
603 } 672 }
604 673
605 } // namespace internal 674 } // namespace internal
606 } // namespace webrtc 675 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/video/end_to_end_tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698