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 |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 | 12 |
| 13 #include <map> | 13 #include <map> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "webrtc/audio/audio_receive_stream.h" | 16 #include "webrtc/audio/audio_receive_stream.h" |
| 17 #include "webrtc/audio/audio_send_stream.h" | 17 #include "webrtc/audio/audio_send_stream.h" |
| 18 #include "webrtc/audio/audio_state.h" | 18 #include "webrtc/audio/audio_state.h" |
| 19 #include "webrtc/audio/scoped_voe_interface.h" | 19 #include "webrtc/audio/scoped_voe_interface.h" |
| 20 #include "webrtc/base/checks.h" | 20 #include "webrtc/base/checks.h" |
| 21 #include "webrtc/base/scoped_ptr.h" | 21 #include "webrtc/base/scoped_ptr.h" |
| 22 #include "webrtc/base/thread_annotations.h" | 22 #include "webrtc/base/thread_annotations.h" |
| 23 #include "webrtc/base/thread_checker.h" | 23 #include "webrtc/base/thread_checker.h" |
| 24 #include "webrtc/base/trace_event.h" | 24 #include "webrtc/base/trace_event.h" |
| 25 #include "webrtc/call.h" | 25 #include "webrtc/call.h" |
| 26 #include "webrtc/call/bitrate_allocator.h" | |
| 26 #include "webrtc/call/congestion_controller.h" | 27 #include "webrtc/call/congestion_controller.h" |
| 27 #include "webrtc/call/rtc_event_log.h" | 28 #include "webrtc/call/rtc_event_log.h" |
| 28 #include "webrtc/common.h" | 29 #include "webrtc/common.h" |
| 29 #include "webrtc/config.h" | 30 #include "webrtc/config.h" |
| 31 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | |
| 32 #include "webrtc/modules/pacing/include/paced_sender.h" | |
| 30 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 33 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
| 31 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 34 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 32 #include "webrtc/modules/utility/include/process_thread.h" | 35 #include "webrtc/modules/utility/include/process_thread.h" |
| 33 #include "webrtc/system_wrappers/include/cpu_info.h" | 36 #include "webrtc/system_wrappers/include/cpu_info.h" |
| 34 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 37 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
| 35 #include "webrtc/system_wrappers/include/logging.h" | 38 #include "webrtc/system_wrappers/include/logging.h" |
| 36 #include "webrtc/system_wrappers/include/metrics.h" | 39 #include "webrtc/system_wrappers/include/metrics.h" |
| 37 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" | 40 #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" |
| 38 #include "webrtc/system_wrappers/include/trace.h" | 41 #include "webrtc/system_wrappers/include/trace.h" |
| 39 #include "webrtc/video/video_receive_stream.h" | 42 #include "webrtc/video/video_receive_stream.h" |
| 40 #include "webrtc/video/video_send_stream.h" | 43 #include "webrtc/video/video_send_stream.h" |
| 41 #include "webrtc/video_engine/call_stats.h" | 44 #include "webrtc/video_engine/call_stats.h" |
| 42 #include "webrtc/voice_engine/include/voe_codec.h" | 45 #include "webrtc/voice_engine/include/voe_codec.h" |
| 43 | 46 |
| 44 namespace webrtc { | 47 namespace webrtc { |
| 45 | 48 |
| 46 const int Call::Config::kDefaultStartBitrateBps = 300000; | 49 const int Call::Config::kDefaultStartBitrateBps = 300000; |
| 47 | 50 |
| 48 namespace internal { | 51 namespace internal { |
| 49 | 52 |
| 50 class Call : public webrtc::Call, public PacketReceiver { | 53 class Call : public webrtc::Call, public PacketReceiver, |
| 54 public BitrateObserver { | |
| 51 public: | 55 public: |
| 52 explicit Call(const Call::Config& config); | 56 explicit Call(const Call::Config& config); |
| 53 virtual ~Call(); | 57 virtual ~Call(); |
| 54 | 58 |
| 55 PacketReceiver* Receiver() override; | 59 PacketReceiver* Receiver() override; |
| 56 | 60 |
| 57 webrtc::AudioSendStream* CreateAudioSendStream( | 61 webrtc::AudioSendStream* CreateAudioSendStream( |
| 58 const webrtc::AudioSendStream::Config& config) override; | 62 const webrtc::AudioSendStream::Config& config) override; |
| 59 void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override; | 63 void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override; |
| 60 | 64 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 79 const uint8_t* packet, | 83 const uint8_t* packet, |
| 80 size_t length, | 84 size_t length, |
| 81 const PacketTime& packet_time) override; | 85 const PacketTime& packet_time) override; |
| 82 | 86 |
| 83 void SetBitrateConfig( | 87 void SetBitrateConfig( |
| 84 const webrtc::Call::Config::BitrateConfig& bitrate_config) override; | 88 const webrtc::Call::Config::BitrateConfig& bitrate_config) override; |
| 85 void SignalNetworkState(NetworkState state) override; | 89 void SignalNetworkState(NetworkState state) override; |
| 86 | 90 |
| 87 void OnSentPacket(const rtc::SentPacket& sent_packet) override; | 91 void OnSentPacket(const rtc::SentPacket& sent_packet) override; |
| 88 | 92 |
| 93 // Implements BitrateObserver. | |
| 94 void OnNetworkChanged(uint32_t bitrate_bps, uint8_t fraction_loss, | |
| 95 int64_t rtt_ms) override; | |
| 96 | |
| 89 private: | 97 private: |
| 90 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, | 98 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, |
| 91 size_t length); | 99 size_t length); |
| 92 DeliveryStatus DeliverRtp(MediaType media_type, | 100 DeliveryStatus DeliverRtp(MediaType media_type, |
| 93 const uint8_t* packet, | 101 const uint8_t* packet, |
| 94 size_t length, | 102 size_t length, |
| 95 const PacketTime& packet_time); | 103 const PacketTime& packet_time); |
| 96 | 104 |
| 97 void ConfigureSync(const std::string& sync_group) | 105 void ConfigureSync(const std::string& sync_group) |
| 98 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); | 106 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); |
| 99 | 107 |
| 100 VoiceEngine* voice_engine() { | 108 VoiceEngine* voice_engine() { |
| 101 internal::AudioState* audio_state = | 109 internal::AudioState* audio_state = |
| 102 static_cast<internal::AudioState*>(config_.audio_state.get()); | 110 static_cast<internal::AudioState*>(config_.audio_state.get()); |
| 103 if (audio_state) | 111 if (audio_state) |
| 104 return audio_state->voice_engine(); | 112 return audio_state->voice_engine(); |
| 105 else | 113 else |
| 106 return nullptr; | 114 return nullptr; |
| 107 } | 115 } |
| 108 | 116 |
| 109 void UpdateHistograms(); | 117 void UpdateHistograms(); |
| 110 | 118 |
| 111 const Clock* const clock_; | 119 const Clock* const clock_; |
| 112 | 120 |
| 113 const int num_cpu_cores_; | 121 const int num_cpu_cores_; |
| 114 const rtc::scoped_ptr<ProcessThread> module_process_thread_; | 122 const rtc::scoped_ptr<ProcessThread> module_process_thread_; |
| 115 const rtc::scoped_ptr<CallStats> call_stats_; | 123 const rtc::scoped_ptr<CallStats> call_stats_; |
| 116 const rtc::scoped_ptr<CongestionController> congestion_controller_; | 124 const rtc::scoped_ptr<BitrateAllocator> bitrate_allocator_; |
| 117 Call::Config config_; | 125 Call::Config config_; |
| 118 rtc::ThreadChecker configuration_thread_checker_; | 126 rtc::ThreadChecker configuration_thread_checker_; |
| 119 | 127 |
| 120 bool network_enabled_; | 128 bool network_enabled_; |
| 121 | 129 |
| 122 rtc::scoped_ptr<RWLockWrapper> receive_crit_; | 130 rtc::scoped_ptr<RWLockWrapper> receive_crit_; |
| 123 // Audio and Video receive streams are owned by the client that creates them. | 131 // Audio and Video receive streams are owned by the client that creates them. |
| 124 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ | 132 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ |
| 125 GUARDED_BY(receive_crit_); | 133 GUARDED_BY(receive_crit_); |
| 126 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ | 134 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 141 RtcEventLog* event_log_ = nullptr; | 149 RtcEventLog* event_log_ = nullptr; |
| 142 | 150 |
| 143 // The RateTrackers are only accessed (exclusively) from DeliverRtp or | 151 // The RateTrackers are only accessed (exclusively) from DeliverRtp or |
| 144 // DeliverRtcp, and from the destructor, and therefore doesn't need any | 152 // DeliverRtcp, and from the destructor, and therefore doesn't need any |
| 145 // explicit synchronization. | 153 // explicit synchronization. |
| 146 rtc::RateTracker received_video_bytes_per_sec_; | 154 rtc::RateTracker received_video_bytes_per_sec_; |
| 147 rtc::RateTracker received_audio_bytes_per_sec_; | 155 rtc::RateTracker received_audio_bytes_per_sec_; |
| 148 rtc::RateTracker received_rtcp_bytes_per_sec_; | 156 rtc::RateTracker received_rtcp_bytes_per_sec_; |
| 149 int64_t first_rtp_packet_received_ms_; | 157 int64_t first_rtp_packet_received_ms_; |
| 150 | 158 |
| 159 const rtc::scoped_ptr<CongestionController> congestion_controller_; | |
| 160 | |
| 151 RTC_DISALLOW_COPY_AND_ASSIGN(Call); | 161 RTC_DISALLOW_COPY_AND_ASSIGN(Call); |
| 152 }; | 162 }; |
| 153 } // namespace internal | 163 } // namespace internal |
| 154 | 164 |
| 155 Call* Call::Create(const Call::Config& config) { | 165 Call* Call::Create(const Call::Config& config) { |
| 156 return new internal::Call(config); | 166 return new internal::Call(config); |
| 157 } | 167 } |
| 158 | 168 |
| 159 namespace internal { | 169 namespace internal { |
| 160 | 170 |
| 161 Call::Call(const Call::Config& config) | 171 Call::Call(const Call::Config& config) |
| 162 : clock_(Clock::GetRealTimeClock()), | 172 : clock_(Clock::GetRealTimeClock()), |
| 163 num_cpu_cores_(CpuInfo::DetectNumberOfCores()), | 173 num_cpu_cores_(CpuInfo::DetectNumberOfCores()), |
| 164 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), | 174 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), |
| 165 call_stats_(new CallStats()), | 175 call_stats_(new CallStats()), |
| 166 congestion_controller_( | 176 bitrate_allocator_(new BitrateAllocator()), |
| 167 new CongestionController(module_process_thread_.get(), | |
| 168 call_stats_.get())), | |
| 169 config_(config), | 177 config_(config), |
| 170 network_enabled_(true), | 178 network_enabled_(true), |
| 171 receive_crit_(RWLockWrapper::CreateRWLock()), | 179 receive_crit_(RWLockWrapper::CreateRWLock()), |
| 172 send_crit_(RWLockWrapper::CreateRWLock()), | 180 send_crit_(RWLockWrapper::CreateRWLock()), |
| 173 received_video_bytes_per_sec_(1000, 1), | 181 received_video_bytes_per_sec_(1000, 1), |
| 174 received_audio_bytes_per_sec_(1000, 1), | 182 received_audio_bytes_per_sec_(1000, 1), |
| 175 received_rtcp_bytes_per_sec_(1000, 1), | 183 received_rtcp_bytes_per_sec_(1000, 1), |
| 176 first_rtp_packet_received_ms_(-1) { | 184 first_rtp_packet_received_ms_(-1), |
| 185 congestion_controller_(new CongestionController( | |
| 186 module_process_thread_.get(), call_stats_.get(), this)) { | |
| 177 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); | 187 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); |
| 178 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, | 188 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, |
| 179 config.bitrate_config.min_bitrate_bps); | 189 config.bitrate_config.min_bitrate_bps); |
| 180 if (config.bitrate_config.max_bitrate_bps != -1) { | 190 if (config.bitrate_config.max_bitrate_bps != -1) { |
| 181 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, | 191 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, |
| 182 config.bitrate_config.start_bitrate_bps); | 192 config.bitrate_config.start_bitrate_bps); |
| 183 } | 193 } |
| 184 if (config.audio_state.get()) { | 194 if (config.audio_state.get()) { |
| 185 ScopedVoEInterface<VoECodec> voe_codec(voice_engine()); | 195 ScopedVoEInterface<VoECodec> voe_codec(voice_engine()); |
| 186 event_log_ = voe_codec->GetEventLog(); | 196 event_log_ = voe_codec->GetEventLog(); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 webrtc::VideoSendStream* Call::CreateVideoSendStream( | 337 webrtc::VideoSendStream* Call::CreateVideoSendStream( |
| 328 const webrtc::VideoSendStream::Config& config, | 338 const webrtc::VideoSendStream::Config& config, |
| 329 const VideoEncoderConfig& encoder_config) { | 339 const VideoEncoderConfig& encoder_config) { |
| 330 TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream"); | 340 TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream"); |
| 331 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 341 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
| 332 | 342 |
| 333 // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if | 343 // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if |
| 334 // the call has already started. | 344 // the call has already started. |
| 335 VideoSendStream* send_stream = new VideoSendStream( | 345 VideoSendStream* send_stream = new VideoSendStream( |
| 336 num_cpu_cores_, module_process_thread_.get(), call_stats_.get(), | 346 num_cpu_cores_, module_process_thread_.get(), call_stats_.get(), |
| 337 congestion_controller_.get(), config, encoder_config, | 347 congestion_controller_.get(), bitrate_allocator_.get(), config, |
| 338 suspended_video_send_ssrcs_); | 348 encoder_config, suspended_video_send_ssrcs_); |
| 339 | 349 |
| 340 if (!network_enabled_) | 350 if (!network_enabled_) |
| 341 send_stream->SignalNetworkState(kNetworkDown); | 351 send_stream->SignalNetworkState(kNetworkDown); |
| 342 | 352 |
| 343 WriteLockScoped write_lock(*send_crit_); | 353 WriteLockScoped write_lock(*send_crit_); |
| 344 for (uint32_t ssrc : config.rtp.ssrcs) { | 354 for (uint32_t ssrc : config.rtp.ssrcs) { |
| 345 RTC_DCHECK(video_send_ssrcs_.find(ssrc) == video_send_ssrcs_.end()); | 355 RTC_DCHECK(video_send_ssrcs_.find(ssrc) == video_send_ssrcs_.end()); |
| 346 video_send_ssrcs_[ssrc] = send_stream; | 356 video_send_ssrcs_[ssrc] = send_stream; |
| 347 } | 357 } |
| 348 video_send_streams_.insert(send_stream); | 358 video_send_streams_.insert(send_stream); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 for (auto& kv : video_receive_ssrcs_) { | 524 for (auto& kv : video_receive_ssrcs_) { |
| 515 kv.second->SignalNetworkState(state); | 525 kv.second->SignalNetworkState(state); |
| 516 } | 526 } |
| 517 } | 527 } |
| 518 } | 528 } |
| 519 | 529 |
| 520 void Call::OnSentPacket(const rtc::SentPacket& sent_packet) { | 530 void Call::OnSentPacket(const rtc::SentPacket& sent_packet) { |
| 521 congestion_controller_->OnSentPacket(sent_packet); | 531 congestion_controller_->OnSentPacket(sent_packet); |
| 522 } | 532 } |
| 523 | 533 |
| 534 void Call::OnNetworkChanged(uint32_t target_bitrate_bps, uint8_t fraction_loss, | |
| 535 int64_t rtt_ms) { | |
| 536 uint32_t allocated_bitrate_bps = bitrate_allocator_->OnNetworkChanged( | |
| 537 target_bitrate_bps, fraction_loss, rtt_ms); | |
| 538 | |
| 539 int pad_up_to_bitrate_bps = 0; | |
| 540 { | |
| 541 ReadLockScoped read_lock(*send_crit_); | |
| 542 // No need to update as long as we're not sending. | |
| 543 if (video_send_streams_.empty()) | |
| 544 return; | |
| 545 | |
| 546 for (VideoSendStream* stream : video_send_streams_) | |
| 547 pad_up_to_bitrate_bps += stream->GetPaddingNeededBps(); | |
| 548 } | |
| 549 // Allocated bitrate might be higher than bitrate estimate if enforcing min | |
| 550 // bitrate, or lower if estimate is higher than the sum of max bitrates, so | |
| 551 // set the pacer bitrate to the maximum of the two. | |
| 552 uint32_t pacer_bitrate_bps = | |
| 553 std::max(target_bitrate_bps, allocated_bitrate_bps); | |
| 554 congestion_controller_->UpdatePacerBitrateKbps( | |
| 555 target_bitrate_bps / 1000, | |
| 556 PacedSender::kDefaultPaceMultiplier * pacer_bitrate_bps / 1000, | |
| 557 pad_up_to_bitrate_bps / 1000); | |
| 558 } | |
| 559 | |
| 560 | |
|
sprang_webrtc
2015/11/12 14:30:22
Wouldn't be even better to move this straight into
mflodman
2015/11/12 16:16:40
I agree that is the right thing to do, but (and I
sprang_webrtc
2015/11/12 16:30:33
Fair enough!
| |
| 524 void Call::ConfigureSync(const std::string& sync_group) { | 561 void Call::ConfigureSync(const std::string& sync_group) { |
| 525 // Set sync only if there was no previous one. | 562 // Set sync only if there was no previous one. |
| 526 if (voice_engine() == nullptr || sync_group.empty()) | 563 if (voice_engine() == nullptr || sync_group.empty()) |
| 527 return; | 564 return; |
| 528 | 565 |
| 529 AudioReceiveStream* sync_audio_stream = nullptr; | 566 AudioReceiveStream* sync_audio_stream = nullptr; |
| 530 // Find existing audio stream. | 567 // Find existing audio stream. |
| 531 const auto it = sync_stream_mapping_.find(sync_group); | 568 const auto it = sync_stream_mapping_.find(sync_group); |
| 532 if (it != sync_stream_mapping_.end()) { | 569 if (it != sync_stream_mapping_.end()) { |
| 533 sync_audio_stream = it->second; | 570 sync_audio_stream = it->second; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 // thread. Then this check can be enabled. | 688 // thread. Then this check can be enabled. |
| 652 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); | 689 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); |
| 653 if (RtpHeaderParser::IsRtcp(packet, length)) | 690 if (RtpHeaderParser::IsRtcp(packet, length)) |
| 654 return DeliverRtcp(media_type, packet, length); | 691 return DeliverRtcp(media_type, packet, length); |
| 655 | 692 |
| 656 return DeliverRtp(media_type, packet, length, packet_time); | 693 return DeliverRtp(media_type, packet, length, packet_time); |
| 657 } | 694 } |
| 658 | 695 |
| 659 } // namespace internal | 696 } // namespace internal |
| 660 } // namespace webrtc | 697 } // namespace webrtc |
| OLD | NEW |