Chromium Code Reviews| Index: webrtc/video/call.cc |
| diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc |
| index cde41bc77a69d589c2cdb18620fbb981371ef9db..84c08609fbd39d8dfeff426d38fefd076345909e 100644 |
| --- a/webrtc/video/call.cc |
| +++ b/webrtc/video/call.cc |
| @@ -65,6 +65,60 @@ class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver { |
| LoadObserver* overuse_callback_ GUARDED_BY(crit_); |
| }; |
| +class SyncGroup { |
|
the sun
2015/06/11 11:52:04
Simplify as discussed offline.
pbos-webrtc
2015/06/11 14:48:53
Done.
|
| + public: |
| + explicit SyncGroup(VoiceEngine* voice_engine) : voice_engine_(voice_engine) { |
| + DCHECK(voice_engine != nullptr); |
| + } |
| + |
| + ~SyncGroup() { |
| + DCHECK(audio_channel_map_.empty()); |
| + DCHECK(video_streams_.empty()); |
| + } |
| + |
| + void AddAudioReceiveStream(AudioReceiveStream* receive_stream, |
| + int channel_id) { |
| + if (sync_channel_ == -1) |
| + SetSyncChannel(channel_id); |
| + audio_channel_map_[receive_stream] = channel_id; |
| + } |
| + |
| + void RemoveAudioReceiveStream(AudioReceiveStream* receive_stream) { |
| + DCHECK(audio_channel_map_.find(receive_stream) != audio_channel_map_.end()); |
| + int old_channel = audio_channel_map_[receive_stream]; |
| + int current_channel = sync_channel_; |
| + audio_channel_map_.erase(receive_stream); |
| + if (old_channel != current_channel) |
| + return; |
| + SetSyncChannel( |
| + audio_channel_map_.empty() ? -1 : audio_channel_map_.begin()->second); |
| + } |
| + |
| + void AddVideoReceiveStream(VideoReceiveStream* receive_stream) { |
| + video_streams_.insert(receive_stream); |
| + if (sync_channel_ == -1) |
| + return; |
| + receive_stream->SetSyncChannel(voice_engine_, sync_channel_); |
| + } |
| + |
| + void RemoveVideoReceiveStream(VideoReceiveStream* receive_stream) { |
| + receive_stream->SetSyncChannel(voice_engine_, -1); |
| + video_streams_.erase(receive_stream); |
| + } |
| + |
| + private: |
| + void SetSyncChannel(int channel_id) { |
| + sync_channel_ = channel_id; |
| + for (VideoReceiveStream* video_stream : video_streams_) |
| + video_stream->SetSyncChannel(voice_engine_, channel_id); |
| + } |
| + |
| + VoiceEngine* const voice_engine_; |
| + int sync_channel_ = -1; |
| + std::map<AudioReceiveStream*, int> audio_channel_map_; |
| + std::set<VideoReceiveStream*> video_streams_; |
| +}; |
| + |
| class Call : public webrtc::Call, public PacketReceiver { |
| public: |
| explicit Call(const Call::Config& config); |
| @@ -109,6 +163,18 @@ class Call : public webrtc::Call, public PacketReceiver { |
| void SetBitrateControllerConfig( |
| const webrtc::Call::Config::BitrateConfig& bitrate_config); |
| + void AddAudioReceiveStreamSync(AudioReceiveStream* stream, |
| + const std::string& sync_group, |
| + int channel_id); |
| + void RemoveAudioReceiveStreamSync(AudioReceiveStream* stream); |
| + |
| + void AddVideoReceiveStreamSync(VideoReceiveStream* stream, |
| + const std::string& sync_group); |
| + void RemoveVideoReceiveStreamSync(VideoReceiveStream* stream); |
| + |
| + SyncGroup* FindSyncGroup(const std::string& sync_group) |
| + EXCLUSIVE_LOCKS_REQUIRED(sync_group_crit_); |
| + |
| const int num_cpu_cores_; |
| const rtc::scoped_ptr<ProcessThread> module_process_thread_; |
| const rtc::scoped_ptr<ChannelGroup> channel_group_; |
| @@ -135,6 +201,13 @@ class Call : public webrtc::Call, public PacketReceiver { |
| std::map<uint32_t, VideoSendStream*> video_send_ssrcs_ GUARDED_BY(send_crit_); |
| std::set<VideoSendStream*> video_send_streams_ GUARDED_BY(send_crit_); |
| + rtc::CriticalSection sync_group_crit_; |
| + std::map<VideoReceiveStream*, std::string> video_sync_groups_ |
| + GUARDED_BY(sync_group_crit_); |
| + std::map<AudioReceiveStream*, std::string> audio_sync_groups_ |
| + GUARDED_BY(sync_group_crit_); |
| + std::map<std::string, SyncGroup*> sync_groups_ GUARDED_BY(sync_group_crit_); |
| + |
| rtc::scoped_ptr<CpuOveruseObserverProxy> overuse_observer_proxy_; |
| VideoSendStream::RtpStateMap suspended_video_send_ssrcs_; |
| @@ -192,6 +265,8 @@ Call::~Call() { |
| CHECK_EQ(0u, audio_receive_ssrcs_.size()); |
| CHECK_EQ(0u, video_receive_ssrcs_.size()); |
| CHECK_EQ(0u, video_receive_streams_.size()); |
| + for (auto& kv : sync_groups_) |
| + delete kv.second; |
| channel_group_->DeleteChannel(base_channel_id_); |
| module_process_thread_->Stop(); |
| @@ -214,6 +289,8 @@ webrtc::AudioReceiveStream* Call::CreateAudioReceiveStream( |
| LOG(LS_INFO) << "CreateAudioReceiveStream: " << config.ToString(); |
| AudioReceiveStream* receive_stream = new AudioReceiveStream( |
| channel_group_->GetRemoteBitrateEstimator(), config); |
| + AddAudioReceiveStreamSync(receive_stream, config.sync_group, |
| + config.channel_id); |
| { |
| WriteLockScoped write_lock(*receive_crit_); |
| DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) == |
| @@ -229,6 +306,7 @@ void Call::DestroyAudioReceiveStream( |
| DCHECK(receive_stream != nullptr); |
| AudioReceiveStream* audio_receive_stream = |
| static_cast<AudioReceiveStream*>(receive_stream); |
| + RemoveAudioReceiveStreamSync(audio_receive_stream); |
| { |
| WriteLockScoped write_lock(*receive_crit_); |
| size_t num_deleted = audio_receive_ssrcs_.erase( |
| @@ -309,6 +387,7 @@ webrtc::VideoReceiveStream* Call::CreateVideoReceiveStream( |
| num_cpu_cores_, base_channel_id_, channel_group_.get(), |
| rtc::AtomicOps::Increment(&next_channel_id_), config, |
| config_.send_transport, config_.voice_engine); |
| + AddVideoReceiveStreamSync(receive_stream, config.sync_group); |
| // This needs to be taken before receive_crit_ as both locks need to be held |
| // while changing network state. |
| @@ -333,7 +412,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_); |
| @@ -353,6 +431,7 @@ void Call::DestroyVideoReceiveStream( |
| video_receive_streams_.erase(receive_stream_impl); |
| } |
| CHECK(receive_stream_impl != nullptr); |
| + RemoveVideoReceiveStreamSync(receive_stream_impl); |
| delete receive_stream_impl; |
| } |
| @@ -428,6 +507,53 @@ void Call::SignalNetworkState(NetworkState state) { |
| } |
| } |
| +void Call::AddAudioReceiveStreamSync(AudioReceiveStream* stream, |
| + const std::string& sync_group, |
| + int channel_id) { |
| + if (!config_.voice_engine || sync_group.empty()) |
| + return; |
| + rtc::CritScope lock(&sync_group_crit_); |
| + audio_sync_groups_[stream] = sync_group; |
| + SyncGroup* group = FindSyncGroup(sync_group); |
| + group->AddAudioReceiveStream(stream, channel_id); |
| +} |
| + |
| +void Call::RemoveAudioReceiveStreamSync(AudioReceiveStream* stream) { |
| + if (!config_.voice_engine) |
| + return; |
| + rtc::CritScope lock(&sync_group_crit_); |
| + SyncGroup* group = FindSyncGroup(audio_sync_groups_[stream]); |
| + group->RemoveAudioReceiveStream(stream); |
| +} |
| + |
| +void Call::AddVideoReceiveStreamSync(VideoReceiveStream* stream, |
| + const std::string& sync_group) { |
| + if (!config_.voice_engine || sync_group.empty()) |
| + return; |
| + rtc::CritScope lock(&sync_group_crit_); |
| + video_sync_groups_[stream] = sync_group; |
| + SyncGroup* group = FindSyncGroup(sync_group); |
| + group->AddVideoReceiveStream(stream); |
| +} |
| + |
| +void Call::RemoveVideoReceiveStreamSync(VideoReceiveStream* stream) { |
| + if (!config_.voice_engine) |
| + return; |
| + rtc::CritScope lock(&sync_group_crit_); |
| + SyncGroup* group = FindSyncGroup(video_sync_groups_[stream]); |
| + group->RemoveVideoReceiveStream(stream); |
| +} |
| + |
| +SyncGroup* Call::FindSyncGroup(const std::string& sync_group) { |
| + DCHECK(!sync_group.empty()); |
| + |
| + if (sync_groups_.find(sync_group) == sync_groups_.end()) |
| + sync_groups_[sync_group] = new SyncGroup(config_.voice_engine); |
| + |
| + SyncGroup* group = sync_groups_[sync_group]; |
| + return group; |
| +} |
| + |
| PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, |
| const uint8_t* packet, |
| size_t length) { |