OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |