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

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: Can't verify the audio stats in this test. Postponing audio stats tests. 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 // The RateTrackers are only accessed (exclusively) from DeliverRtp or
144 // DeliverRtcp, and from the destructor, and therefore doesn't need any
145 // explicit synchronization.
146 rtc::RateTracker received_video_bytes_per_sec_;
147 rtc::RateTracker received_audio_bytes_per_sec_;
148 rtc::RateTracker received_rtcp_bytes_per_sec_;
149 int64_t first_rtp_packet_received_ms_;
pbos-webrtc 2015/11/11 16:24:29 (I assume the corner case where RTCP arrives first
stefan-webrtc 2015/11/11 18:15:22 Its a very slim corner case. If rtcp arrives first
150
138 RTC_DISALLOW_COPY_AND_ASSIGN(Call); 151 RTC_DISALLOW_COPY_AND_ASSIGN(Call);
139 }; 152 };
140 } // namespace internal 153 } // namespace internal
141 154
142 Call* Call::Create(const Call::Config& config) { 155 Call* Call::Create(const Call::Config& config) {
143 return new internal::Call(config); 156 return new internal::Call(config);
144 } 157 }
145 158
146 namespace internal { 159 namespace internal {
147 160
148 Call::Call(const Call::Config& config) 161 Call::Call(const Call::Config& config)
149 : num_cpu_cores_(CpuInfo::DetectNumberOfCores()), 162 : clock_(Clock::GetRealTimeClock()),
163 num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
150 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), 164 module_process_thread_(ProcessThread::Create("ModuleProcessThread")),
151 call_stats_(new CallStats()), 165 call_stats_(new CallStats()),
152 congestion_controller_(new CongestionController( 166 congestion_controller_(
153 module_process_thread_.get(), call_stats_.get())), 167 new CongestionController(module_process_thread_.get(),
168 call_stats_.get())),
154 config_(config), 169 config_(config),
155 network_enabled_(true), 170 network_enabled_(true),
156 receive_crit_(RWLockWrapper::CreateRWLock()), 171 receive_crit_(RWLockWrapper::CreateRWLock()),
157 send_crit_(RWLockWrapper::CreateRWLock()) { 172 send_crit_(RWLockWrapper::CreateRWLock()),
173 received_video_bytes_per_sec_(1000, 1),
174 received_audio_bytes_per_sec_(1000, 1),
175 received_rtcp_bytes_per_sec_(1000, 1),
176 first_rtp_packet_received_ms_(-1) {
158 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); 177 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0);
159 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, 178 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps,
160 config.bitrate_config.min_bitrate_bps); 179 config.bitrate_config.min_bitrate_bps);
161 if (config.bitrate_config.max_bitrate_bps != -1) { 180 if (config.bitrate_config.max_bitrate_bps != -1) {
162 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, 181 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps,
163 config.bitrate_config.start_bitrate_bps); 182 config.bitrate_config.start_bitrate_bps);
164 } 183 }
165 if (config.audio_state.get()) { 184 if (config.audio_state.get()) {
166 ScopedVoEInterface<VoECodec> voe_codec(voice_engine()); 185 ScopedVoEInterface<VoECodec> voe_codec(voice_engine());
167 event_log_ = voe_codec->GetEventLog(); 186 event_log_ = voe_codec->GetEventLog();
168 } 187 }
169 188
170 Trace::CreateTrace(); 189 Trace::CreateTrace();
171 module_process_thread_->Start(); 190 module_process_thread_->Start();
172 module_process_thread_->RegisterModule(call_stats_.get()); 191 module_process_thread_->RegisterModule(call_stats_.get());
173 192
174 congestion_controller_->SetBweBitrates( 193 congestion_controller_->SetBweBitrates(
175 config_.bitrate_config.min_bitrate_bps, 194 config_.bitrate_config.min_bitrate_bps,
176 config_.bitrate_config.start_bitrate_bps, 195 config_.bitrate_config.start_bitrate_bps,
177 config_.bitrate_config.max_bitrate_bps); 196 config_.bitrate_config.max_bitrate_bps);
178 197
179 congestion_controller_->GetBitrateController()->SetEventLog(event_log_); 198 congestion_controller_->GetBitrateController()->SetEventLog(event_log_);
180 } 199 }
181 200
182 Call::~Call() { 201 Call::~Call() {
202 UpdateHistograms();
183 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); 203 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
184 RTC_CHECK(audio_send_ssrcs_.empty()); 204 RTC_CHECK(audio_send_ssrcs_.empty());
185 RTC_CHECK(video_send_ssrcs_.empty()); 205 RTC_CHECK(video_send_ssrcs_.empty());
186 RTC_CHECK(video_send_streams_.empty()); 206 RTC_CHECK(video_send_streams_.empty());
187 RTC_CHECK(audio_receive_ssrcs_.empty()); 207 RTC_CHECK(audio_receive_ssrcs_.empty());
188 RTC_CHECK(video_receive_ssrcs_.empty()); 208 RTC_CHECK(video_receive_ssrcs_.empty());
189 RTC_CHECK(video_receive_streams_.empty()); 209 RTC_CHECK(video_receive_streams_.empty());
190 210
191 module_process_thread_->DeRegisterModule(call_stats_.get()); 211 module_process_thread_->DeRegisterModule(call_stats_.get());
192 module_process_thread_->Stop(); 212 module_process_thread_->Stop();
193 Trace::ReturnTrace(); 213 Trace::ReturnTrace();
194 } 214 }
195 215
216 void Call::UpdateHistograms() {
217 if (first_rtp_packet_received_ms_ == -1)
218 return;
219 int64_t elapsed_sec =
220 (clock_->TimeInMilliseconds() - first_rtp_packet_received_ms_) / 1000;
221 if (elapsed_sec < metrics::kMinRunTimeInSeconds)
222 return;
223 int audio_bitrate_kbps =
224 received_audio_bytes_per_sec_.ComputeTotalRate() * 8 / 1000;
225 int video_bitrate_kbps =
226 received_video_bytes_per_sec_.ComputeTotalRate() * 8 / 1000;
227 int rtcp_bitrate_bps = received_rtcp_bytes_per_sec_.ComputeTotalRate() * 8;
228 if (video_bitrate_kbps > 0) {
229 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
230 video_bitrate_kbps);
231 }
232 if (audio_bitrate_kbps > 0) {
233 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
234 audio_bitrate_kbps);
235 }
236 if (rtcp_bitrate_bps > 0) {
237 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
238 rtcp_bitrate_bps);
239 }
240 RTC_HISTOGRAM_COUNTS_100000(
241 "WebRTC.Call.BitrateReceivedInKbps",
242 audio_bitrate_kbps + video_bitrate_kbps + rtcp_bitrate_bps / 1000);
243 }
244
196 PacketReceiver* Call::Receiver() { 245 PacketReceiver* Call::Receiver() {
197 // TODO(solenberg): Some test cases in EndToEndTest use this from a different 246 // TODO(solenberg): Some test cases in EndToEndTest use this from a different
198 // thread. Re-enable once that is fixed. 247 // thread. Re-enable once that is fixed.
199 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); 248 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
200 return this; 249 return this;
201 } 250 }
202 251
203 webrtc::AudioSendStream* Call::CreateAudioSendStream( 252 webrtc::AudioSendStream* Call::CreateAudioSendStream(
204 const webrtc::AudioSendStream::Config& config) { 253 const webrtc::AudioSendStream::Config& config) {
205 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); 254 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 } 569 }
521 } 570 }
522 571
523 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, 572 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
524 const uint8_t* packet, 573 const uint8_t* packet,
525 size_t length) { 574 size_t length) {
526 // TODO(pbos): Figure out what channel needs it actually. 575 // TODO(pbos): Figure out what channel needs it actually.
527 // Do NOT broadcast! Also make sure it's a valid packet. 576 // Do NOT broadcast! Also make sure it's a valid packet.
528 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that 577 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that
529 // there's no receiver of the packet. 578 // there's no receiver of the packet.
579 received_rtcp_bytes_per_sec_.AddSamples(length);
530 bool rtcp_delivered = false; 580 bool rtcp_delivered = false;
531 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { 581 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
532 ReadLockScoped read_lock(*receive_crit_); 582 ReadLockScoped read_lock(*receive_crit_);
533 for (VideoReceiveStream* stream : video_receive_streams_) { 583 for (VideoReceiveStream* stream : video_receive_streams_) {
534 if (stream->DeliverRtcp(packet, length)) { 584 if (stream->DeliverRtcp(packet, length)) {
535 rtcp_delivered = true; 585 rtcp_delivered = true;
536 if (event_log_) 586 if (event_log_)
537 event_log_->LogRtcpPacket(true, media_type, packet, length); 587 event_log_->LogRtcpPacket(true, media_type, packet, length);
538 } 588 }
539 } 589 }
(...skipping 12 matching lines...) Expand all
552 } 602 }
553 603
554 PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type, 604 PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
555 const uint8_t* packet, 605 const uint8_t* packet,
556 size_t length, 606 size_t length,
557 const PacketTime& packet_time) { 607 const PacketTime& packet_time) {
558 // Minimum RTP header size. 608 // Minimum RTP header size.
559 if (length < 12) 609 if (length < 12)
560 return DELIVERY_PACKET_ERROR; 610 return DELIVERY_PACKET_ERROR;
561 611
612 if (first_rtp_packet_received_ms_ == -1)
613 first_rtp_packet_received_ms_ = clock_->TimeInMilliseconds();
614
562 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]); 615 uint32_t ssrc = ByteReader<uint32_t>::ReadBigEndian(&packet[8]);
563
564 ReadLockScoped read_lock(*receive_crit_); 616 ReadLockScoped read_lock(*receive_crit_);
565 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) { 617 if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
566 auto it = audio_receive_ssrcs_.find(ssrc); 618 auto it = audio_receive_ssrcs_.find(ssrc);
567 if (it != audio_receive_ssrcs_.end()) { 619 if (it != audio_receive_ssrcs_.end()) {
620 received_audio_bytes_per_sec_.AddSamples(length);
568 auto status = it->second->DeliverRtp(packet, length, packet_time) 621 auto status = it->second->DeliverRtp(packet, length, packet_time)
569 ? DELIVERY_OK 622 ? DELIVERY_OK
570 : DELIVERY_PACKET_ERROR; 623 : DELIVERY_PACKET_ERROR;
571 if (status == DELIVERY_OK && event_log_) 624 if (status == DELIVERY_OK && event_log_)
572 event_log_->LogRtpHeader(true, media_type, packet, length); 625 event_log_->LogRtpHeader(true, media_type, packet, length);
573 return status; 626 return status;
574 } 627 }
575 } 628 }
576 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { 629 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
577 auto it = video_receive_ssrcs_.find(ssrc); 630 auto it = video_receive_ssrcs_.find(ssrc);
578 if (it != video_receive_ssrcs_.end()) { 631 if (it != video_receive_ssrcs_.end()) {
632 received_video_bytes_per_sec_.AddSamples(length);
579 auto status = it->second->DeliverRtp(packet, length, packet_time) 633 auto status = it->second->DeliverRtp(packet, length, packet_time)
580 ? DELIVERY_OK 634 ? DELIVERY_OK
581 : DELIVERY_PACKET_ERROR; 635 : DELIVERY_PACKET_ERROR;
582 if (status == DELIVERY_OK && event_log_) 636 if (status == DELIVERY_OK && event_log_)
583 event_log_->LogRtpHeader(true, media_type, packet, length); 637 event_log_->LogRtpHeader(true, media_type, packet, length);
584 return status; 638 return status;
585 } 639 }
586 } 640 }
587 return DELIVERY_UNKNOWN_SSRC; 641 return DELIVERY_UNKNOWN_SSRC;
pbos-webrtc 2015/11/11 16:24:29 Do you wanna track unknown bitrate as well?
stefan-webrtc 2015/11/11 18:15:22 We can add that later if we see a need.
588 } 642 }
589 643
590 PacketReceiver::DeliveryStatus Call::DeliverPacket( 644 PacketReceiver::DeliveryStatus Call::DeliverPacket(
591 MediaType media_type, 645 MediaType media_type,
592 const uint8_t* packet, 646 const uint8_t* packet,
593 size_t length, 647 size_t length,
594 const PacketTime& packet_time) { 648 const PacketTime& packet_time) {
595 // TODO(solenberg): Tests call this function on a network thread, libjingle 649 // TODO(solenberg): Tests call this function on a network thread, libjingle
596 // calls on the worker thread. We should move towards always using a network 650 // calls on the worker thread. We should move towards always using a network
597 // thread. Then this check can be enabled. 651 // thread. Then this check can be enabled.
598 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); 652 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread());
599 if (RtpHeaderParser::IsRtcp(packet, length)) 653 if (RtpHeaderParser::IsRtcp(packet, length))
600 return DeliverRtcp(media_type, packet, length); 654 return DeliverRtcp(media_type, packet, length);
601 655
602 return DeliverRtp(media_type, packet, length, packet_time); 656 return DeliverRtp(media_type, packet, length, packet_time);
603 } 657 }
604 658
605 } // namespace internal 659 } // namespace internal
606 } // namespace webrtc 660 } // 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