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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 | 102 |
103 private: | 103 private: |
104 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, | 104 DeliveryStatus DeliverRtcp(MediaType media_type, const uint8_t* packet, |
105 size_t length); | 105 size_t length); |
106 DeliveryStatus DeliverRtp(MediaType media_type, const uint8_t* packet, | 106 DeliveryStatus DeliverRtp(MediaType media_type, const uint8_t* packet, |
107 size_t length); | 107 size_t length); |
108 | 108 |
109 void SetBitrateControllerConfig( | 109 void SetBitrateControllerConfig( |
110 const webrtc::Call::Config::BitrateConfig& bitrate_config); | 110 const webrtc::Call::Config::BitrateConfig& bitrate_config); |
111 | 111 |
| 112 void ConfigureSync(const std::string& sync_group) |
| 113 EXCLUSIVE_LOCKS_REQUIRED(receive_crit_); |
| 114 |
112 const int num_cpu_cores_; | 115 const int num_cpu_cores_; |
113 const rtc::scoped_ptr<ProcessThread> module_process_thread_; | 116 const rtc::scoped_ptr<ProcessThread> module_process_thread_; |
114 const rtc::scoped_ptr<ChannelGroup> channel_group_; | 117 const rtc::scoped_ptr<ChannelGroup> channel_group_; |
115 const int base_channel_id_; | 118 const int base_channel_id_; |
116 volatile int next_channel_id_; | 119 volatile int next_channel_id_; |
117 Call::Config config_; | 120 Call::Config config_; |
118 | 121 |
119 // Needs to be held while write-locking |receive_crit_| or |send_crit_|. This | 122 // Needs to be held while write-locking |receive_crit_| or |send_crit_|. This |
120 // ensures that we have a consistent network state signalled to all senders | 123 // ensures that we have a consistent network state signalled to all senders |
121 // and receivers. | 124 // and receivers. |
122 rtc::CriticalSection network_enabled_crit_; | 125 rtc::CriticalSection network_enabled_crit_; |
123 bool network_enabled_ GUARDED_BY(network_enabled_crit_); | 126 bool network_enabled_ GUARDED_BY(network_enabled_crit_); |
124 TransportAdapter transport_adapter_; | 127 TransportAdapter transport_adapter_; |
125 | 128 |
126 rtc::scoped_ptr<RWLockWrapper> receive_crit_; | 129 rtc::scoped_ptr<RWLockWrapper> receive_crit_; |
127 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ | 130 std::map<uint32_t, AudioReceiveStream*> audio_receive_ssrcs_ |
128 GUARDED_BY(receive_crit_); | 131 GUARDED_BY(receive_crit_); |
129 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ | 132 std::map<uint32_t, VideoReceiveStream*> video_receive_ssrcs_ |
130 GUARDED_BY(receive_crit_); | 133 GUARDED_BY(receive_crit_); |
131 std::set<VideoReceiveStream*> video_receive_streams_ | 134 std::set<VideoReceiveStream*> video_receive_streams_ |
132 GUARDED_BY(receive_crit_); | 135 GUARDED_BY(receive_crit_); |
| 136 std::map<std::string, AudioReceiveStream*> sync_stream_mapping_ |
| 137 GUARDED_BY(receive_crit_); |
133 | 138 |
134 rtc::scoped_ptr<RWLockWrapper> send_crit_; | 139 rtc::scoped_ptr<RWLockWrapper> send_crit_; |
135 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); | 140 std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); |
136 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); | 141 std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); |
137 | 142 |
138 rtc::scoped_ptr<CpuOveruseObserverProxy> overuse_observer_proxy_; | 143 rtc::scoped_ptr<CpuOveruseObserverProxy> overuse_observer_proxy_; |
139 | 144 |
140 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; | 145 VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; |
141 | 146 |
142 DISALLOW_COPY_AND_ASSIGN(Call); | 147 DISALLOW_COPY_AND_ASSIGN(Call); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 const webrtc::AudioReceiveStream::Config& config) { | 217 const webrtc::AudioReceiveStream::Config& config) { |
213 TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream"); | 218 TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream"); |
214 LOG(LS_INFO) << "CreateAudioReceiveStream: " << config.ToString(); | 219 LOG(LS_INFO) << "CreateAudioReceiveStream: " << config.ToString(); |
215 AudioReceiveStream* receive_stream = new AudioReceiveStream( | 220 AudioReceiveStream* receive_stream = new AudioReceiveStream( |
216 channel_group_->GetRemoteBitrateEstimator(), config); | 221 channel_group_->GetRemoteBitrateEstimator(), config); |
217 { | 222 { |
218 WriteLockScoped write_lock(*receive_crit_); | 223 WriteLockScoped write_lock(*receive_crit_); |
219 DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) == | 224 DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) == |
220 audio_receive_ssrcs_.end()); | 225 audio_receive_ssrcs_.end()); |
221 audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; | 226 audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; |
| 227 ConfigureSync(config.sync_group); |
222 } | 228 } |
223 return receive_stream; | 229 return receive_stream; |
224 } | 230 } |
225 | 231 |
226 void Call::DestroyAudioReceiveStream( | 232 void Call::DestroyAudioReceiveStream( |
227 webrtc::AudioReceiveStream* receive_stream) { | 233 webrtc::AudioReceiveStream* receive_stream) { |
228 TRACE_EVENT0("webrtc", "Call::DestroyAudioReceiveStream"); | 234 TRACE_EVENT0("webrtc", "Call::DestroyAudioReceiveStream"); |
229 DCHECK(receive_stream != nullptr); | 235 DCHECK(receive_stream != nullptr); |
230 AudioReceiveStream* audio_receive_stream = | 236 AudioReceiveStream* audio_receive_stream = |
231 static_cast<AudioReceiveStream*>(receive_stream); | 237 static_cast<AudioReceiveStream*>(receive_stream); |
232 { | 238 { |
233 WriteLockScoped write_lock(*receive_crit_); | 239 WriteLockScoped write_lock(*receive_crit_); |
234 size_t num_deleted = audio_receive_ssrcs_.erase( | 240 size_t num_deleted = audio_receive_ssrcs_.erase( |
235 audio_receive_stream->config().rtp.remote_ssrc); | 241 audio_receive_stream->config().rtp.remote_ssrc); |
236 DCHECK(num_deleted == 1); | 242 DCHECK(num_deleted == 1); |
| 243 const std::string& sync_group = audio_receive_stream->config().sync_group; |
| 244 const auto it = sync_stream_mapping_.find(sync_group); |
| 245 if (it != sync_stream_mapping_.end() && |
| 246 it->second == audio_receive_stream) { |
| 247 sync_stream_mapping_.erase(it); |
| 248 ConfigureSync(sync_group); |
| 249 } |
237 } | 250 } |
238 delete audio_receive_stream; | 251 delete audio_receive_stream; |
239 } | 252 } |
240 | 253 |
241 webrtc::VideoSendStream* Call::CreateVideoSendStream( | 254 webrtc::VideoSendStream* Call::CreateVideoSendStream( |
242 const webrtc::VideoSendStream::Config& config, | 255 const webrtc::VideoSendStream::Config& config, |
243 const VideoEncoderConfig& encoder_config) { | 256 const VideoEncoderConfig& encoder_config) { |
244 TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream"); | 257 TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream"); |
245 LOG(LS_INFO) << "CreateVideoSendStream: " << config.ToString(); | 258 LOG(LS_INFO) << "CreateVideoSendStream: " << config.ToString(); |
246 DCHECK(!config.rtp.ssrcs.empty()); | 259 DCHECK(!config.rtp.ssrcs.empty()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) == | 330 DCHECK(video_receive_ssrcs_.find(config.rtp.remote_ssrc) == |
318 video_receive_ssrcs_.end()); | 331 video_receive_ssrcs_.end()); |
319 video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; | 332 video_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream; |
320 // TODO(pbos): Configure different RTX payloads per receive payload. | 333 // TODO(pbos): Configure different RTX payloads per receive payload. |
321 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = | 334 VideoReceiveStream::Config::Rtp::RtxMap::const_iterator it = |
322 config.rtp.rtx.begin(); | 335 config.rtp.rtx.begin(); |
323 if (it != config.rtp.rtx.end()) | 336 if (it != config.rtp.rtx.end()) |
324 video_receive_ssrcs_[it->second.ssrc] = receive_stream; | 337 video_receive_ssrcs_[it->second.ssrc] = receive_stream; |
325 video_receive_streams_.insert(receive_stream); | 338 video_receive_streams_.insert(receive_stream); |
326 | 339 |
| 340 ConfigureSync(config.sync_group); |
| 341 |
327 if (!network_enabled_) | 342 if (!network_enabled_) |
328 receive_stream->SignalNetworkState(kNetworkDown); | 343 receive_stream->SignalNetworkState(kNetworkDown); |
| 344 |
329 return receive_stream; | 345 return receive_stream; |
330 } | 346 } |
331 | 347 |
332 void Call::DestroyVideoReceiveStream( | 348 void Call::DestroyVideoReceiveStream( |
333 webrtc::VideoReceiveStream* receive_stream) { | 349 webrtc::VideoReceiveStream* receive_stream) { |
334 TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream"); | 350 TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream"); |
335 DCHECK(receive_stream != nullptr); | 351 DCHECK(receive_stream != nullptr); |
336 | |
337 VideoReceiveStream* receive_stream_impl = nullptr; | 352 VideoReceiveStream* receive_stream_impl = nullptr; |
338 { | 353 { |
339 WriteLockScoped write_lock(*receive_crit_); | 354 WriteLockScoped write_lock(*receive_crit_); |
340 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a | 355 // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a |
341 // separate SSRC there can be either one or two. | 356 // separate SSRC there can be either one or two. |
342 auto it = video_receive_ssrcs_.begin(); | 357 auto it = video_receive_ssrcs_.begin(); |
343 while (it != video_receive_ssrcs_.end()) { | 358 while (it != video_receive_ssrcs_.end()) { |
344 if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) { | 359 if (it->second == static_cast<VideoReceiveStream*>(receive_stream)) { |
345 if (receive_stream_impl != nullptr) | 360 if (receive_stream_impl != nullptr) |
346 DCHECK(receive_stream_impl == it->second); | 361 DCHECK(receive_stream_impl == it->second); |
347 receive_stream_impl = it->second; | 362 receive_stream_impl = it->second; |
348 video_receive_ssrcs_.erase(it++); | 363 video_receive_ssrcs_.erase(it++); |
349 } else { | 364 } else { |
350 ++it; | 365 ++it; |
351 } | 366 } |
352 } | 367 } |
353 video_receive_streams_.erase(receive_stream_impl); | 368 video_receive_streams_.erase(receive_stream_impl); |
| 369 CHECK(receive_stream_impl != nullptr); |
| 370 ConfigureSync(receive_stream_impl->config().sync_group); |
354 } | 371 } |
355 CHECK(receive_stream_impl != nullptr); | |
356 delete receive_stream_impl; | 372 delete receive_stream_impl; |
357 } | 373 } |
358 | 374 |
359 Call::Stats Call::GetStats() const { | 375 Call::Stats Call::GetStats() const { |
360 Stats stats; | 376 Stats stats; |
361 // Fetch available send/receive bitrates. | 377 // Fetch available send/receive bitrates. |
362 uint32_t send_bandwidth = 0; | 378 uint32_t send_bandwidth = 0; |
363 channel_group_->GetBitrateController()->AvailableBandwidth(&send_bandwidth); | 379 channel_group_->GetBitrateController()->AvailableBandwidth(&send_bandwidth); |
364 std::vector<unsigned int> ssrcs; | 380 std::vector<unsigned int> ssrcs; |
365 uint32_t recv_bandwidth = 0; | 381 uint32_t recv_bandwidth = 0; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 } | 437 } |
422 } | 438 } |
423 { | 439 { |
424 ReadLockScoped write_lock(*receive_crit_); | 440 ReadLockScoped write_lock(*receive_crit_); |
425 for (auto& kv : video_receive_ssrcs_) { | 441 for (auto& kv : video_receive_ssrcs_) { |
426 kv.second->SignalNetworkState(state); | 442 kv.second->SignalNetworkState(state); |
427 } | 443 } |
428 } | 444 } |
429 } | 445 } |
430 | 446 |
| 447 void Call::ConfigureSync(const std::string& sync_group) { |
| 448 // Set sync only if there was no previous one. |
| 449 if (config_.voice_engine == nullptr || sync_group.empty()) |
| 450 return; |
| 451 |
| 452 AudioReceiveStream* sync_audio_stream = nullptr; |
| 453 // Find existing audio stream. |
| 454 const auto it = sync_stream_mapping_.find(sync_group); |
| 455 if (it != sync_stream_mapping_.end()) { |
| 456 sync_audio_stream = it->second; |
| 457 } else { |
| 458 // No configured audio stream, see if we can find one. |
| 459 for (const auto& kv : audio_receive_ssrcs_) { |
| 460 if (kv.second->config().sync_group == sync_group) { |
| 461 if (sync_audio_stream != nullptr) { |
| 462 LOG(LS_WARNING) << "Attempting to sync more than one audio stream " |
| 463 "within the same sync group. This is not " |
| 464 "supported in the current implementation."; |
| 465 break; |
| 466 } |
| 467 sync_audio_stream = kv.second; |
| 468 } |
| 469 } |
| 470 } |
| 471 if (sync_audio_stream) |
| 472 sync_stream_mapping_[sync_group] = sync_audio_stream; |
| 473 size_t num_synced_streams = 0; |
| 474 for (VideoReceiveStream* video_stream : video_receive_streams_) { |
| 475 if (video_stream->config().sync_group != sync_group) |
| 476 continue; |
| 477 ++num_synced_streams; |
| 478 if (num_synced_streams > 1) { |
| 479 // TODO(pbos): Support synchronizing more than one A/V pair. |
| 480 // https://code.google.com/p/webrtc/issues/detail?id=4762 |
| 481 LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair " |
| 482 "within the same sync group. This is not supported in " |
| 483 "the current implementation."; |
| 484 } |
| 485 // Only sync the first A/V pair within this sync group. |
| 486 if (sync_audio_stream != nullptr && num_synced_streams == 1) { |
| 487 video_stream->SetSyncChannel(config_.voice_engine, |
| 488 sync_audio_stream->config().voe_channel_id); |
| 489 } else { |
| 490 video_stream->SetSyncChannel(config_.voice_engine, -1); |
| 491 } |
| 492 } |
| 493 } |
| 494 |
431 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, | 495 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, |
432 const uint8_t* packet, | 496 const uint8_t* packet, |
433 size_t length) { | 497 size_t length) { |
434 // TODO(pbos): Figure out what channel needs it actually. | 498 // TODO(pbos): Figure out what channel needs it actually. |
435 // Do NOT broadcast! Also make sure it's a valid packet. | 499 // Do NOT broadcast! Also make sure it's a valid packet. |
436 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that | 500 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that |
437 // there's no receiver of the packet. | 501 // there's no receiver of the packet. |
438 bool rtcp_delivered = false; | 502 bool rtcp_delivered = false; |
439 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { | 503 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { |
440 ReadLockScoped read_lock(*receive_crit_); | 504 ReadLockScoped read_lock(*receive_crit_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 const uint8_t* packet, | 548 const uint8_t* packet, |
485 size_t length) { | 549 size_t length) { |
486 if (RtpHeaderParser::IsRtcp(packet, length)) | 550 if (RtpHeaderParser::IsRtcp(packet, length)) |
487 return DeliverRtcp(media_type, packet, length); | 551 return DeliverRtcp(media_type, packet, length); |
488 | 552 |
489 return DeliverRtp(media_type, packet, length); | 553 return DeliverRtp(media_type, packet, length); |
490 } | 554 } |
491 | 555 |
492 } // namespace internal | 556 } // namespace internal |
493 } // namespace webrtc | 557 } // namespace webrtc |
OLD | NEW |