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" |
| 19 #include "webrtc/audio/scoped_voe_interface.h" |
18 #include "webrtc/base/checks.h" | 20 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/scoped_ptr.h" | 21 #include "webrtc/base/scoped_ptr.h" |
20 #include "webrtc/base/thread_annotations.h" | 22 #include "webrtc/base/thread_annotations.h" |
21 #include "webrtc/base/thread_checker.h" | 23 #include "webrtc/base/thread_checker.h" |
22 #include "webrtc/base/trace_event.h" | 24 #include "webrtc/base/trace_event.h" |
23 #include "webrtc/call.h" | 25 #include "webrtc/call.h" |
24 #include "webrtc/call/congestion_controller.h" | 26 #include "webrtc/call/congestion_controller.h" |
25 #include "webrtc/call/rtc_event_log.h" | 27 #include "webrtc/call/rtc_event_log.h" |
26 #include "webrtc/common.h" | 28 #include "webrtc/common.h" |
27 #include "webrtc/config.h" | 29 #include "webrtc/config.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, | 89 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, |
88 size_t length); | 90 size_t length); |
89 DeliveryStatus DeliverRtp(MediaType media_type, | 91 DeliveryStatus DeliverRtp(MediaType media_type, |
90 const uint8_t* packet, | 92 const uint8_t* packet, |
91 size_t length, | 93 size_t length, |
92 const PacketTime& packet_time); | 94 const PacketTime& packet_time); |
93 | 95 |
94 void ConfigureSync(const std::string& sync_group) | 96 void ConfigureSync(const std::string& sync_group) |
95 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); | 97 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); |
96 | 98 |
| 99 webrtc::internal::AudioState* audio_state() { |
| 100 return static_cast<webrtc::internal::AudioState*>( |
| 101 config_.audio_state.get()); |
| 102 } |
| 103 VoiceEngine* voice_engine() { |
| 104 if (!config_.audio_state.get()) |
| 105 return nullptr; |
| 106 return audio_state()->voice_engine(); |
| 107 } |
| 108 |
97 const int num_cpu_cores_; | 109 const int num_cpu_cores_; |
98 const rtc::scoped_ptr<ProcessThread> module_process_thread_; | 110 const rtc::scoped_ptr<ProcessThread> module_process_thread_; |
99 const rtc::scoped_ptr<CallStats> call_stats_; | 111 const rtc::scoped_ptr<CallStats> call_stats_; |
100 const rtc::scoped_ptr<CongestionController> congestion_controller_; | 112 const rtc::scoped_ptr<CongestionController> congestion_controller_; |
101 Call::Config config_; | 113 Call::Config config_; |
102 rtc::ThreadChecker configuration_thread_checker_; | 114 rtc::ThreadChecker configuration_thread_checker_; |
103 | 115 |
104 bool network_enabled_; | 116 bool network_enabled_; |
105 | 117 |
106 rtc::scoped_ptr<RWLockWrapper> receive_crit_; | 118 rtc::scoped_ptr<RWLockWrapper> receive_crit_; |
107 // Audio and Video receive streams are owned by the client that creates them. | 119 // Audio and Video receive streams are owned by the client that creates them. |
108 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ | 120 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ |
109 GUARDED_BY(receive_crit_); | 121 GUARDED_BY(receive_crit_); |
110 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ | 122 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ |
111 GUARDED_BY(receive_crit_); | 123 GUARDED_BY(receive_crit_); |
112 std::set<VideoReceiveStream*> video_receive_streams_ | 124 std::set<VideoReceiveStream*> video_receive_streams_ |
113 GUARDED_BY(receive_crit_); | 125 GUARDED_BY(receive_crit_); |
114 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_ | 126 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_ |
115 GUARDED_BY(receive_crit_); | 127 GUARDED_BY(receive_crit_); |
116 | 128 |
117 rtc::scoped_ptr<RWLockWrapper> send_crit_; | 129 rtc::scoped_ptr<RWLockWrapper> send_crit_; |
118 // Audio and Video send streams are owned by the client that creates them. | 130 // Audio and Video send streams are owned by the client that creates them. |
119 std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_); | 131 std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_ GUARDED_BY(send_crit_); |
120 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); | 132 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); |
121 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); | 133 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); |
122 | 134 |
123 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; | 135 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; |
124 | 136 |
125 RtcEventLog* event_log_ = nullptr; | 137 RtcEventLog* event_log_ = nullptr; |
126 VoECodec* voe_codec_ = nullptr; | |
127 | 138 |
128 RTC_DISALLOW_COPY_AND_ASSIGN(Call); | 139 RTC_DISALLOW_COPY_AND_ASSIGN(Call); |
129 }; | 140 }; |
130 } // namespace internal | 141 } // namespace internal |
131 | 142 |
132 Call* Call::Create(const Call::Config& config) { | 143 Call* Call::Create(const Call::Config& config) { |
133 return new internal::Call(config); | 144 return new internal::Call(config); |
134 } | 145 } |
135 | 146 |
136 namespace internal { | 147 namespace internal { |
137 | 148 |
138 Call::Call(const Call::Config& config) | 149 Call::Call(const Call::Config& config) |
139 : num_cpu_cores_(CpuInfo::DetectNumberOfCores()), | 150 : num_cpu_cores_(CpuInfo::DetectNumberOfCores()), |
140 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), | 151 module_process_thread_(ProcessThread::Create("ModuleProcessThread")), |
141 call_stats_(new CallStats()), | 152 call_stats_(new CallStats()), |
142 congestion_controller_(new CongestionController( | 153 congestion_controller_(new CongestionController( |
143 module_process_thread_.get(), call_stats_.get())), | 154 module_process_thread_.get(), call_stats_.get())), |
144 config_(config), | 155 config_(config), |
145 network_enabled_(true), | 156 network_enabled_(true), |
146 receive_crit_(RWLockWrapper::CreateRWLock()), | 157 receive_crit_(RWLockWrapper::CreateRWLock()), |
147 send_crit_(RWLockWrapper::CreateRWLock()) { | 158 send_crit_(RWLockWrapper::CreateRWLock()) { |
148 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); | 159 RTC_DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0); |
149 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, | 160 RTC_DCHECK_GE(config.bitrate_config.start_bitrate_bps, |
150 config.bitrate_config.min_bitrate_bps); | 161 config.bitrate_config.min_bitrate_bps); |
151 if (config.bitrate_config.max_bitrate_bps != -1) { | 162 if (config.bitrate_config.max_bitrate_bps != -1) { |
152 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, | 163 RTC_DCHECK_GE(config.bitrate_config.max_bitrate_bps, |
153 config.bitrate_config.start_bitrate_bps); | 164 config.bitrate_config.start_bitrate_bps); |
154 } | 165 } |
155 if (config.voice_engine) { | 166 if (config.audio_state.get()) { |
156 // Keep a reference to VoECodec, so we're sure the VoiceEngine lives for the | 167 ScopedVoEInterface<VoECodec> voe_codec(voice_engine()); |
157 // duration of the call. | 168 event_log_ = voe_codec->GetEventLog(); |
158 voe_codec_ = VoECodec::GetInterface(config.voice_engine); | |
159 if (voe_codec_) | |
160 event_log_ = voe_codec_->GetEventLog(); | |
161 } | 169 } |
162 | 170 |
163 Trace::CreateTrace(); | 171 Trace::CreateTrace(); |
164 module_process_thread_->Start(); | 172 module_process_thread_->Start(); |
165 module_process_thread_->RegisterModule(call_stats_.get()); | 173 module_process_thread_->RegisterModule(call_stats_.get()); |
166 | 174 |
167 congestion_controller_->SetBweBitrates( | 175 congestion_controller_->SetBweBitrates( |
168 config_.bitrate_config.min_bitrate_bps, | 176 config_.bitrate_config.min_bitrate_bps, |
169 config_.bitrate_config.start_bitrate_bps, | 177 config_.bitrate_config.start_bitrate_bps, |
170 config_.bitrate_config.max_bitrate_bps); | 178 config_.bitrate_config.max_bitrate_bps); |
171 } | 179 } |
172 | 180 |
173 Call::~Call() { | 181 Call::~Call() { |
174 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 182 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
175 RTC_CHECK(audio_send_ssrcs_.empty()); | 183 RTC_CHECK(audio_send_ssrcs_.empty()); |
176 RTC_CHECK(video_send_ssrcs_.empty()); | 184 RTC_CHECK(video_send_ssrcs_.empty()); |
177 RTC_CHECK(video_send_streams_.empty()); | 185 RTC_CHECK(video_send_streams_.empty()); |
178 RTC_CHECK(audio_receive_ssrcs_.empty()); | 186 RTC_CHECK(audio_receive_ssrcs_.empty()); |
179 RTC_CHECK(video_receive_ssrcs_.empty()); | 187 RTC_CHECK(video_receive_ssrcs_.empty()); |
180 RTC_CHECK(video_receive_streams_.empty()); | 188 RTC_CHECK(video_receive_streams_.empty()); |
181 | 189 |
182 module_process_thread_->DeRegisterModule(call_stats_.get()); | 190 module_process_thread_->DeRegisterModule(call_stats_.get()); |
183 module_process_thread_->Stop(); | 191 module_process_thread_->Stop(); |
184 Trace::ReturnTrace(); | 192 Trace::ReturnTrace(); |
185 | |
186 if (voe_codec_) | |
187 voe_codec_->Release(); | |
188 } | 193 } |
189 | 194 |
190 PacketReceiver* Call::Receiver() { | 195 PacketReceiver* Call::Receiver() { |
191 // TODO(solenberg): Some test cases in EndToEndTest use this from a different | 196 // TODO(solenberg): Some test cases in EndToEndTest use this from a different |
192 // thread. Re-enable once that is fixed. | 197 // thread. Re-enable once that is fixed. |
193 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 198 // RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
194 return this; | 199 return this; |
195 } | 200 } |
196 | 201 |
197 webrtc::AudioSendStream* Call::CreateAudioSendStream( | 202 webrtc::AudioSendStream* Call::CreateAudioSendStream( |
198 const webrtc::AudioSendStream::Config& config) { | 203 const webrtc::AudioSendStream::Config& config) { |
199 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); | 204 TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream"); |
200 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 205 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
201 AudioSendStream* send_stream = | 206 AudioSendStream* send_stream = new AudioSendStream(config, audio_state()); |
202 new AudioSendStream(config, config_.voice_engine); | |
203 if (!network_enabled_) | 207 if (!network_enabled_) |
204 send_stream->SignalNetworkState(kNetworkDown); | 208 send_stream->SignalNetworkState(kNetworkDown); |
205 { | 209 { |
206 WriteLockScoped write_lock(*send_crit_); | 210 WriteLockScoped write_lock(*send_crit_); |
207 RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) == | 211 RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) == |
208 audio_send_ssrcs_.end()); | 212 audio_send_ssrcs_.end()); |
209 audio_send_ssrcs_[config.rtp.ssrc] = send_stream; | 213 audio_send_ssrcs_[config.rtp.ssrc] = send_stream; |
210 } | 214 } |
211 return send_stream; | 215 return send_stream; |
212 } | 216 } |
(...skipping 15 matching lines...) Expand all Loading... |
228 } | 232 } |
229 delete audio_send_stream; | 233 delete audio_send_stream; |
230 } | 234 } |
231 | 235 |
232 webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream( | 236 webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream( |
233 const webrtc::AudioReceiveStream::Config& config) { | 237 const webrtc::AudioReceiveStream::Config& config) { |
234 TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream"); | 238 TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream"); |
235 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 239 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
236 AudioReceiveStream* receive_stream = new AudioReceiveStream( | 240 AudioReceiveStream* receive_stream = new AudioReceiveStream( |
237 congestion_controller_->GetRemoteBitrateEstimator(false), config, | 241 congestion_controller_->GetRemoteBitrateEstimator(false), config, |
238 config_.voice_engine); | 242 audio_state()); |
239 { | 243 { |
240 WriteLockScoped write_lock(*receive_crit_); | 244 WriteLockScoped write_lock(*receive_crit_); |
241 RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) == | 245 RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) == |
242 audio_receive_ssrcs_.end()); | 246 audio_receive_ssrcs_.end()); |
243 audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; | 247 audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; |
244 ConfigureSync(config.sync_group); | 248 ConfigureSync(config.sync_group); |
245 } | 249 } |
246 return receive_stream; | 250 return receive_stream; |
247 } | 251 } |
248 | 252 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 335 |
332 delete send_stream_impl; | 336 delete send_stream_impl; |
333 } | 337 } |
334 | 338 |
335 webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream( | 339 webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream( |
336 const webrtc::VideoReceiveStream::Config& config) { | 340 const webrtc::VideoReceiveStream::Config& config) { |
337 TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream"); | 341 TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream"); |
338 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); | 342 RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread()); |
339 VideoReceiveStream* receive_stream = new VideoReceiveStream( | 343 VideoReceiveStream* receive_stream = new VideoReceiveStream( |
340 num_cpu_cores_, congestion_controller_.get(), config, | 344 num_cpu_cores_, congestion_controller_.get(), config, |
341 config_.voice_engine, module_process_thread_.get(), call_stats_.get()); | 345 voice_engine(), module_process_thread_.get(), call_stats_.get()); |
342 | 346 |
343 WriteLockScoped write_lock(*receive_crit_); | 347 WriteLockScoped write_lock(*receive_crit_); |
344 RTC_DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) == | 348 RTC_DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) == |
345 video_receive_ssrcs_.end()); | 349 video_receive_ssrcs_.end()); |
346 video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; | 350 video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; |
347 // TODO(pbos): Configure different RTX payloads per receive payload. | 351 // TODO(pbos): Configure different RTX payloads per receive payload. |
348 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = | 352 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = |
349 config.rtp.rtx.begin(); | 353 config.rtp.rtx.begin(); |
350 if (it != config.rtp.rtx.end()) | 354 if (it != config.rtp.rtx.end()) |
351 video_receive_ssrcs_[it->second.ssrc] = receive_stream; | 355 video_receive_ssrcs_[it->second.ssrc] = receive_stream; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 465 } |
462 } | 466 } |
463 } | 467 } |
464 | 468 |
465 void Call::OnSentPacket(const rtc::SentPacket& sent_packet) { | 469 void Call::OnSentPacket(const rtc::SentPacket& sent_packet) { |
466 congestion_controller_->OnSentPacket(sent_packet); | 470 congestion_controller_->OnSentPacket(sent_packet); |
467 } | 471 } |
468 | 472 |
469 void Call::ConfigureSync(const std::string& sync_group) { | 473 void Call::ConfigureSync(const std::string& sync_group) { |
470 // Set sync only if there was no previous one. | 474 // Set sync only if there was no previous one. |
471 if (config_.voice_engine == nullptr || sync_group.empty()) | 475 if (voice_engine() == nullptr || sync_group.empty()) |
472 return; | 476 return; |
473 | 477 |
474 AudioReceiveStream* sync_audio_stream = nullptr; | 478 AudioReceiveStream* sync_audio_stream = nullptr; |
475 // Find existing audio stream. | 479 // Find existing audio stream. |
476 const auto it = sync_stream_mapping_.find(sync_group); | 480 const auto it = sync_stream_mapping_.find(sync_group); |
477 if (it != sync_stream_mapping_.end()) { | 481 if (it != sync_stream_mapping_.end()) { |
478 sync_audio_stream = it->second; | 482 sync_audio_stream = it->second; |
479 } else { | 483 } else { |
480 // No configured audio stream, see if we can find one. | 484 // No configured audio stream, see if we can find one. |
481 for (const auto& kv : audio_receive_ssrcs_) { | 485 for (const auto& kv : audio_receive_ssrcs_) { |
(...skipping 17 matching lines...) Expand all Loading... |
499 ++num_synced_streams; | 503 ++num_synced_streams; |
500 if (num_synced_streams > 1) { | 504 if (num_synced_streams > 1) { |
501 // TODO(pbos): Support synchronizing more than one A/V pair. | 505 // TODO(pbos): Support synchronizing more than one A/V pair. |
502 // https://code.google.com/p/webrtc/issues/detail?id=4762 | 506 // https://code.google.com/p/webrtc/issues/detail?id=4762 |
503 LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair " | 507 LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair " |
504 "within the same sync group. This is not supported in " | 508 "within the same sync group. This is not supported in " |
505 "the current implementation."; | 509 "the current implementation."; |
506 } | 510 } |
507 // Only sync the first A/V pair within this sync group. | 511 // Only sync the first A/V pair within this sync group. |
508 if (sync_audio_stream != nullptr && num_synced_streams == 1) { | 512 if (sync_audio_stream != nullptr && num_synced_streams == 1) { |
509 video_stream->SetSyncChannel(config_.voice_engine, | 513 video_stream->SetSyncChannel(voice_engine(), |
510 sync_audio_stream->config().voe_channel_id); | 514 sync_audio_stream->config().voe_channel_id); |
511 } else { | 515 } else { |
512 video_stream->SetSyncChannel(config_.voice_engine, -1); | 516 video_stream->SetSyncChannel(voice_engine(), -1); |
513 } | 517 } |
514 } | 518 } |
515 } | 519 } |
516 | 520 |
517 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, | 521 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, |
518 const uint8_t* packet, | 522 const uint8_t* packet, |
519 size_t length) { | 523 size_t length) { |
520 // TODO(pbos): Figure out what channel needs it actually. | 524 // TODO(pbos): Figure out what channel needs it actually. |
521 // Do NOT broadcast! Also make sure it's a valid packet. | 525 // Do NOT broadcast! Also make sure it's a valid packet. |
522 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that | 526 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 // thread. Then this check can be enabled. | 595 // thread. Then this check can be enabled. |
592 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); | 596 // RTC_DCHECK(!configuration_thread_checker_.CalledOnValidThread()); |
593 if (RtpHeaderParser::IsRtcp(packet, length)) | 597 if (RtpHeaderParser::IsRtcp(packet, length)) |
594 return DeliverRtcp(media_type, packet, length); | 598 return DeliverRtcp(media_type, packet, length); |
595 | 599 |
596 return DeliverRtp(media_type, packet, length, packet_time); | 600 return DeliverRtp(media_type, packet, length, packet_time); |
597 } | 601 } |
598 | 602 |
599 } // namespace internal | 603 } // namespace internal |
600 } // namespace webrtc | 604 } // namespace webrtc |
OLD | NEW |