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