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 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 LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair " | |
| 480 "within the same sync group. This is not supported in " | |
| 481 "the current implementation."; | |
| 
 
hta-webrtc
2015/07/06 19:04:00
Should there be a bug number filed to track this r
 
pbos-webrtc
2015/07/09 10:21:49
https://code.google.com/p/webrtc/issues/detail?id=
 
 | |
| 482 } | |
| 483 // Only sync the first A/V pair within this sync group. | |
| 484 if (sync_audio_stream != nullptr && num_synced_streams == 1) { | |
| 485 video_stream->SetSyncChannel(config_.voice_engine, | |
| 486 sync_audio_stream->config().voe_channel_id); | |
| 487 } else { | |
| 488 video_stream->SetSyncChannel(config_.voice_engine, -1); | |
| 489 } | |
| 490 } | |
| 491 } | |
| 492 | |
| 431 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, | 493 PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, | 
| 432 const uint8_t* packet, | 494 const uint8_t* packet, | 
| 433 size_t length) { | 495 size_t length) { | 
| 434 // TODO(pbos): Figure out what channel needs it actually. | 496 // TODO(pbos): Figure out what channel needs it actually. | 
| 435 // Do NOT broadcast! Also make sure it's a valid packet. | 497 // Do NOT broadcast! Also make sure it's a valid packet. | 
| 436 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that | 498 // Return DELIVERY_UNKNOWN_SSRC if it can be determined that | 
| 437 // there's no receiver of the packet. | 499 // there's no receiver of the packet. | 
| 438 bool rtcp_delivered = false; | 500 bool rtcp_delivered = false; | 
| 439 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { | 501 if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) { | 
| 440 ReadLockScoped read_lock(*receive_crit_); | 502 ReadLockScoped read_lock(*receive_crit_); | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 const uint8_t* packet, | 546 const uint8_t* packet, | 
| 485 size_t length) { | 547 size_t length) { | 
| 486 if (RtpHeaderParser::IsRtcp(packet, length)) | 548 if (RtpHeaderParser::IsRtcp(packet, length)) | 
| 487 return DeliverRtcp(media_type, packet, length); | 549 return DeliverRtcp(media_type, packet, length); | 
| 488 | 550 | 
| 489 return DeliverRtp(media_type, packet, length); | 551 return DeliverRtp(media_type, packet, length); | 
| 490 } | 552 } | 
| 491 | 553 | 
| 492 } // namespace internal | 554 } // namespace internal | 
| 493 } // namespace webrtc | 555 } // namespace webrtc | 
| OLD | NEW |