| Index: webrtc/video/call.cc
|
| diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc
|
| index 39eb7d6bbc3c968cb08deae4643ff79dffc536c3..a73932509b1c7876eb747fe43f164c6b77cd8f75 100644
|
| --- a/webrtc/video/call.cc
|
| +++ b/webrtc/video/call.cc
|
| @@ -109,6 +109,9 @@ class Call : public webrtc::Call, public PacketReceiver {
|
| void SetBitrateControllerConfig(
|
| const webrtc::Call::Config::BitrateConfig& bitrate_config);
|
|
|
| + void ConfigureSync(const std::string& sync_group)
|
| + EXCLUSIVE_LOCKS_REQUIRED(receive_crit_);
|
| +
|
| const int num_cpu_cores_;
|
| const rtc::scoped_ptr<ProcessThread> module_process_thread_;
|
| const rtc::scoped_ptr<ChannelGroup> channel_group_;
|
| @@ -130,6 +133,8 @@ class Call : public webrtc::Call, public PacketReceiver {
|
| GUARDED_BY(receive_crit_);
|
| std::set<VideoReceiveStream*> video_receive_streams_
|
| GUARDED_BY(receive_crit_);
|
| + std::map<std::string, AudioReceiveStream*> sync_stream_mapping_
|
| + GUARDED_BY(receive_crit_);
|
|
|
| rtc::scoped_ptr<RWLockWrapper> send_crit_;
|
| std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_);
|
| @@ -219,6 +224,7 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream(
|
| DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
|
| audio_receive_ssrcs_.end());
|
| audio_receive_ssrcs_[config.rtp.remote_ssrc] = receive_stream;
|
| + ConfigureSync(config.sync_group);
|
| }
|
| return receive_stream;
|
| }
|
| @@ -234,6 +240,13 @@ void Call::DestroyAudioReceiveStream(
|
| size_t num_deleted = audio_receive_ssrcs_.erase(
|
| audio_receive_stream->config().rtp.remote_ssrc);
|
| DCHECK(num_deleted == 1);
|
| + const std::string& sync_group = audio_receive_stream->config().sync_group;
|
| + const auto it = sync_stream_mapping_.find(sync_group);
|
| + if (it != sync_stream_mapping_.end() &&
|
| + it->second == audio_receive_stream) {
|
| + sync_stream_mapping_.erase(it);
|
| + ConfigureSync(sync_group);
|
| + }
|
| }
|
| delete audio_receive_stream;
|
| }
|
| @@ -324,8 +337,11 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream(
|
| video_receive_ssrcs_[it->second.ssrc] = receive_stream;
|
| video_receive_streams_.insert(receive_stream);
|
|
|
| + ConfigureSync(config.sync_group);
|
| +
|
| if (!network_enabled_)
|
| receive_stream->SignalNetworkState(kNetworkDown);
|
| +
|
| return receive_stream;
|
| }
|
|
|
| @@ -333,7 +349,6 @@ void Call::DestroyVideoReceiveStream(
|
| webrtc::VideoReceiveStream* receive_stream) {
|
| TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream");
|
| DCHECK(receive_stream != nullptr);
|
| -
|
| VideoReceiveStream* receive_stream_impl = nullptr;
|
| {
|
| WriteLockScoped write_lock(*receive_crit_);
|
| @@ -351,8 +366,9 @@ void Call::DestroyVideoReceiveStream(
|
| }
|
| }
|
| video_receive_streams_.erase(receive_stream_impl);
|
| + CHECK(receive_stream_impl != nullptr);
|
| + ConfigureSync(receive_stream_impl->config().sync_group);
|
| }
|
| - CHECK(receive_stream_impl != nullptr);
|
| delete receive_stream_impl;
|
| }
|
|
|
| @@ -428,6 +444,54 @@ void Call::SignalNetworkState(NetworkState state) {
|
| }
|
| }
|
|
|
| +void Call::ConfigureSync(const std::string& sync_group) {
|
| + // Set sync only if there was no previous one.
|
| + if (config_.voice_engine == nullptr || sync_group.empty())
|
| + return;
|
| +
|
| + AudioReceiveStream* sync_audio_stream = nullptr;
|
| + // Find existing audio stream.
|
| + const auto it = sync_stream_mapping_.find(sync_group);
|
| + if (it != sync_stream_mapping_.end()) {
|
| + sync_audio_stream = it->second;
|
| + } else {
|
| + // No configured audio stream, see if we can find one.
|
| + for (const auto& kv : audio_receive_ssrcs_) {
|
| + if (kv.second->config().sync_group == sync_group) {
|
| + if (sync_audio_stream != nullptr) {
|
| + LOG(LS_WARNING) << "Attempting to sync more than one audio stream "
|
| + "within the same sync group. This is not "
|
| + "supported in the current implementation.";
|
| + break;
|
| + }
|
| + sync_audio_stream = kv.second;
|
| + }
|
| + }
|
| + }
|
| + if (sync_audio_stream)
|
| + sync_stream_mapping_[sync_group] = sync_audio_stream;
|
| + size_t num_synced_streams = 0;
|
| + for (VideoReceiveStream* video_stream : video_receive_streams_) {
|
| + if (video_stream->config().sync_group != sync_group)
|
| + continue;
|
| + ++num_synced_streams;
|
| + if (num_synced_streams > 1) {
|
| + // TODO(pbos): Support synchronizing more than one A/V pair.
|
| + // https://code.google.com/p/webrtc/issues/detail?id=4762
|
| + LOG(LS_WARNING) << "Attempting to sync more than one audio/video pair "
|
| + "within the same sync group. This is not supported in "
|
| + "the current implementation.";
|
| + }
|
| + // Only sync the first A/V pair within this sync group.
|
| + if (sync_audio_stream != nullptr && num_synced_streams == 1) {
|
| + video_stream->SetSyncChannel(config_.voice_engine,
|
| + sync_audio_stream->config().voe_channel_id);
|
| + } else {
|
| + video_stream->SetSyncChannel(config_.voice_engine, -1);
|
| + }
|
| + }
|
| +}
|
| +
|
| PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
|
| const uint8_t* packet,
|
| size_t length) {
|
|
|