Chromium Code Reviews| 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 |