From a50e6f073deecfd9004e6e4946eabd8c34621608 Mon Sep 17 00:00:00 2001 From: "stefan@webrtc.org" Date: Mon, 9 Mar 2015 10:06:40 +0000 Subject: [PATCH] Move ownership of vie_encoders and vie_channels into the channel group. BUG=4323 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/44369004 Cr-Commit-Position: refs/heads/master@{#8647} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8647 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/video_engine/vie_base_impl.cc | 2 +- webrtc/video_engine/vie_channel_group.cc | 233 ++++++++++++++++- webrtc/video_engine/vie_channel_group.h | 53 +++- webrtc/video_engine/vie_channel_manager.cc | 288 ++++----------------- webrtc/video_engine/vie_channel_manager.h | 21 +- 5 files changed, 311 insertions(+), 286 deletions(-) diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc index 4b977de8e..ca7fd5097 100644 --- a/webrtc/video_engine/vie_base_impl.cc +++ b/webrtc/video_engine/vie_base_impl.cc @@ -211,7 +211,7 @@ int ViEBaseImpl::DeleteChannel(const int video_channel) { // Deregister the ViEEncoder if no other channel is using it. ViEEncoder* vie_encoder = cs.Encoder(video_channel); - if (cs.ChannelUsingViEEncoder(video_channel) == false) { + if (!cs.ChannelUsingViEEncoder(video_channel)) { ViEInputManagerScoped is(*(shared_data_.input_manager())); ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder); if (provider) { diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc index c91c9a97d..afa2d8b54 100644 --- a/webrtc/video_engine/vie_channel_group.cc +++ b/webrtc/video_engine/vie_channel_group.cc @@ -10,6 +10,7 @@ #include "webrtc/video_engine/vie_channel_group.h" +#include "webrtc/base/checks.h" #include "webrtc/base/thread_annotations.h" #include "webrtc/common.h" #include "webrtc/experiments.h" @@ -20,9 +21,11 @@ #include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/video_engine/call_stats.h" #include "webrtc/video_engine/encoder_state_feedback.h" +#include "webrtc/video_engine/payload_router.h" #include "webrtc/video_engine/vie_channel.h" #include "webrtc/video_engine/vie_encoder.h" #include "webrtc/video_engine/vie_remb.h" +#include "webrtc/voice_engine/include/voe_video_sync.h" namespace webrtc { namespace { @@ -151,7 +154,7 @@ ChannelGroup::ChannelGroup(ProcessThread* process_thread, const Config* config) own_config_.reset(new Config); config_ = own_config_.get(); } - assert(config_); // Must have a valid config pointer here. + DCHECK(config_); // Must have a valid config pointer here. remote_bitrate_estimator_.reset( new WrappingBitrateEstimator(remb_.get(), @@ -170,44 +173,248 @@ ChannelGroup::~ChannelGroup() { process_thread_->DeRegisterModule(call_stats_.get()); process_thread_->DeRegisterModule(remote_bitrate_estimator_.get()); call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get()); - assert(channels_.empty()); - assert(!remb_->InUse()); + DCHECK(channels_.empty()); + DCHECK(channel_map_.empty()); + DCHECK(!remb_->InUse()); + DCHECK(vie_encoder_map_.empty()); +} + +bool ChannelGroup::CreateSendChannel(int channel_id, + int engine_id, + int number_of_cores, + bool disable_default_encoder) { + rtc::scoped_ptr vie_encoder(new ViEEncoder( + channel_id, number_of_cores, *config_, *process_thread_, + bitrate_allocator_.get(), bitrate_controller_.get(), false)); + if (!vie_encoder->Init()) { + return false; + } + ViEEncoder* encoder = vie_encoder.get(); + if (!CreateChannel(channel_id, engine_id, number_of_cores, + vie_encoder.release(), true, disable_default_encoder)) { + return false; + } + ViEChannel* channel = channel_map_[channel_id]; + // Connect the encoder with the send packet router, to enable sending. + encoder->StartThreadsAndSetSharedMembers(channel->send_payload_router(), + channel->vcm_protection_callback()); + + // Register the ViEEncoder to get key frame requests for this channel. + unsigned int ssrc = 0; + int stream_idx = 0; + channel->GetLocalSSRC(stream_idx, &ssrc); + encoder_state_feedback_->AddEncoder(ssrc, encoder); + std::list ssrcs; + ssrcs.push_back(ssrc); + encoder->SetSsrcs(ssrcs); + return true; +} + +bool ChannelGroup::CreateReceiveChannel(int channel_id, + int engine_id, + int base_channel_id, + int number_of_cores, + bool disable_default_encoder) { + ViEEncoder* encoder = GetEncoder(base_channel_id); + return CreateChannel(channel_id, engine_id, number_of_cores, encoder, false, + disable_default_encoder); +} + +bool ChannelGroup::CreateChannel(int channel_id, + int engine_id, + int number_of_cores, + ViEEncoder* vie_encoder, + bool sender, + bool disable_default_encoder) { + DCHECK(vie_encoder); + + rtc::scoped_ptr channel(new ViEChannel( + channel_id, engine_id, number_of_cores, *config_, *process_thread_, + encoder_state_feedback_->GetRtcpIntraFrameObserver(), + bitrate_controller_->CreateRtcpBandwidthObserver(), + remote_bitrate_estimator_.get(), call_stats_->rtcp_rtt_stats(), + vie_encoder->GetPacedSender(), sender, disable_default_encoder)); + if (channel->Init() != 0) { + return false; + } + if (!disable_default_encoder) { + VideoCodec encoder; + if (vie_encoder->GetEncoder(&encoder) != 0) { + return false; + } + if (sender && channel->SetSendCodec(encoder) != 0) { + return false; + } + } + + // Register the channel to receive stats updates. + call_stats_->RegisterStatsObserver(channel->GetStatsObserver()); + + // Store the channel, add it to the channel group and save the vie_encoder. + channel_map_[channel_id] = channel.release(); + vie_encoder_map_[channel_id] = vie_encoder; + + return true; +} + +void ChannelGroup::DeleteChannel(int channel_id) { + ViEChannel* vie_channel = PopChannel(channel_id); + + ViEEncoder* vie_encoder = GetEncoder(channel_id); + DCHECK(vie_encoder != NULL); + + call_stats_->DeregisterStatsObserver(vie_channel->GetStatsObserver()); + SetChannelRembStatus(channel_id, false, false, vie_channel); + + // If we're owning the encoder, remove the feedback and stop all encoding + // threads and processing. This must be done before deleting the channel. + if (vie_encoder->channel_id() == channel_id) { + encoder_state_feedback_->RemoveEncoder(vie_encoder); + vie_encoder->StopThreadsAndRemoveSharedMembers(); + } + + unsigned int remote_ssrc = 0; + vie_channel->GetRemoteSSRC(&remote_ssrc); + RemoveChannel(channel_id); + remote_bitrate_estimator_->RemoveStream(remote_ssrc); + + // Check if other channels are using the same encoder. + if (OtherChannelsUsingEncoder(channel_id)) { + vie_encoder = NULL; + } else { + // Delete later when we've released the critsect. + } + + // We can't erase the item before we've checked for other channels using + // same ViEEncoder. + PopEncoder(channel_id); + + delete vie_channel; + // Leave the write critsect before deleting the objects. + // Deleting a channel can cause other objects, such as renderers, to be + // deleted, which might take time. + // If statment just to show that this object is not always deleted. + if (vie_encoder) { + LOG(LS_VERBOSE) << "ViEEncoder deleted for channel " << channel_id; + delete vie_encoder; + } + + LOG(LS_VERBOSE) << "Channel deleted " << channel_id; } void ChannelGroup::AddChannel(int channel_id) { channels_.insert(channel_id); } -void ChannelGroup::RemoveChannel(int channel_id, unsigned int ssrc) { +void ChannelGroup::RemoveChannel(int channel_id) { channels_.erase(channel_id); - remote_bitrate_estimator_->RemoveStream(ssrc); } -bool ChannelGroup::HasChannel(int channel_id) { +bool ChannelGroup::HasChannel(int channel_id) const { return channels_.find(channel_id) != channels_.end(); } -bool ChannelGroup::Empty() { +bool ChannelGroup::Empty() const { return channels_.empty(); } -BitrateAllocator* ChannelGroup::GetBitrateAllocator() { - return bitrate_allocator_.get(); +ViEChannel* ChannelGroup::GetChannel(int channel_id) const { + ChannelMap::const_iterator it = channel_map_.find(channel_id); + if (it == channel_map_.end()) { + LOG(LS_ERROR) << "Channel doesn't exist " << channel_id; + return NULL; + } + return it->second; } -BitrateController* ChannelGroup::GetBitrateController() { +ViEEncoder* ChannelGroup::GetEncoder(int channel_id) const { + EncoderMap::const_iterator it = vie_encoder_map_.find(channel_id); + if (it == vie_encoder_map_.end()) { + printf("No encoder found: %d\n", channel_id); + return NULL; + } + return it->second; +} + +ViEChannel* ChannelGroup::PopChannel(int channel_id) { + ChannelMap::iterator c_it = channel_map_.find(channel_id); + DCHECK(c_it != channel_map_.end()); + ViEChannel* channel = c_it->second; + channel_map_.erase(c_it); + + return channel; +} + +ViEEncoder* ChannelGroup::PopEncoder(int channel_id) { + EncoderMap::iterator e_it = vie_encoder_map_.find(channel_id); + DCHECK(e_it != vie_encoder_map_.end()); + ViEEncoder* encoder = e_it->second; + vie_encoder_map_.erase(e_it); + + return encoder; +} + +std::vector ChannelGroup::GetChannelIds() const { + std::vector ids; + for (auto channel : channel_map_) + ids.push_back(channel.first); + return ids; +} + +bool ChannelGroup::OtherChannelsUsingEncoder(int channel_id) const { + EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); + if (orig_it == vie_encoder_map_.end()) { + // No ViEEncoder for this channel. + return false; + } + + // Loop through all other channels to see if anyone points at the same + // ViEEncoder. + for (EncoderMap::const_iterator comp_it = vie_encoder_map_.begin(); + comp_it != vie_encoder_map_.end(); ++comp_it) { + // Make sure we're not comparing the same channel with itself. + if (comp_it->first != channel_id) { + if (comp_it->second == orig_it->second) { + return true; + } + } + } + return false; +} + +void ChannelGroup::SetSyncInterface(VoEVideoSync* sync_interface) { + for (auto channel : channel_map_) { + channel.second->SetVoiceChannel(-1, sync_interface); + } +} + +void ChannelGroup::GetChannelsUsingEncoder(int channel_id, + ChannelList* channels) const { + EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); + + for (ChannelMap::const_iterator c_it = channel_map_.begin(); + c_it != channel_map_.end(); ++c_it) { + EncoderMap::const_iterator comp_it = vie_encoder_map_.find(c_it->first); + DCHECK(comp_it != vie_encoder_map_.end()); + if (comp_it->second == orig_it->second) { + channels->push_back(c_it->second); + } + } +} + +BitrateController* ChannelGroup::GetBitrateController() const { return bitrate_controller_.get(); } -RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() { +RemoteBitrateEstimator* ChannelGroup::GetRemoteBitrateEstimator() const { return remote_bitrate_estimator_.get(); } -CallStats* ChannelGroup::GetCallStats() { +CallStats* ChannelGroup::GetCallStats() const { return call_stats_.get(); } -EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() { +EncoderStateFeedback* ChannelGroup::GetEncoderStateFeedback() const { return encoder_state_feedback_.get(); } diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h index 9a2fd2acc..a5fad4129 100644 --- a/webrtc/video_engine/vie_channel_group.h +++ b/webrtc/video_engine/vie_channel_group.h @@ -11,7 +11,10 @@ #ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_GROUP_H_ #define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_GROUP_H_ +#include +#include #include +#include #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" @@ -27,6 +30,9 @@ class RemoteBitrateEstimator; class ViEChannel; class ViEEncoder; class VieRemb; +class VoEVideoSync; + +typedef std::list ChannelList; // Channel group contains data common for several channels. All channels in the // group are assumed to send/receive data to the same end-point. @@ -34,22 +40,37 @@ class ChannelGroup : public BitrateObserver { public: ChannelGroup(ProcessThread* process_thread, const Config* config); ~ChannelGroup(); - + bool CreateSendChannel(int channel_id, + int engine_id, + int number_of_cores, + bool disable_default_encoder); + bool CreateReceiveChannel(int channel_id, + int engine_id, + int base_channel_id, + int number_of_cores, + bool disable_default_encoder); + void DeleteChannel(int channel_id); void AddChannel(int channel_id); - void RemoveChannel(int channel_id, unsigned int ssrc); - bool HasChannel(int channel_id); - bool Empty(); + void RemoveChannel(int channel_id); + bool HasChannel(int channel_id) const; + bool Empty() const; + ViEChannel* GetChannel(int channel_id) const; + ViEEncoder* GetEncoder(int channel_id) const; + std::vector GetChannelIds() const; + bool OtherChannelsUsingEncoder(int channel_id) const; + void GetChannelsUsingEncoder(int channel_id, ChannelList* channels) const; + + void SetSyncInterface(VoEVideoSync* sync_interface); void SetChannelRembStatus(int channel_id, bool sender, bool receiver, ViEChannel* channel); - BitrateAllocator* GetBitrateAllocator(); - BitrateController* GetBitrateController(); - CallStats* GetCallStats(); - RemoteBitrateEstimator* GetRemoteBitrateEstimator(); - EncoderStateFeedback* GetEncoderStateFeedback(); + BitrateController* GetBitrateController() const; + CallStats* GetCallStats() const; + RemoteBitrateEstimator* GetRemoteBitrateEstimator() const; + EncoderStateFeedback* GetEncoderStateFeedback() const; // Implements BitrateObserver. void OnNetworkChanged(uint32_t target_bitrate_bps, @@ -57,7 +78,18 @@ class ChannelGroup : public BitrateObserver { int64_t rtt) override; private: + typedef std::map ChannelMap; typedef std::set ChannelSet; + typedef std::map EncoderMap; + + bool CreateChannel(int channel_id, + int engine_id, + int number_of_cores, + ViEEncoder* vie_encoder, + bool sender, + bool disable_default_encoder); + ViEChannel* PopChannel(int channel_id); + ViEEncoder* PopEncoder(int channel_id); rtc::scoped_ptr remb_; rtc::scoped_ptr bitrate_allocator_; @@ -66,6 +98,9 @@ class ChannelGroup : public BitrateObserver { rtc::scoped_ptr remote_bitrate_estimator_; rtc::scoped_ptr encoder_state_feedback_; ChannelSet channels_; + ChannelMap channel_map_; + // Maps Channel id -> ViEEncoder. + EncoderMap vie_encoder_map_; const Config* config_; // Placeholder for the case where this owns the config. rtc::scoped_ptr own_config_; diff --git a/webrtc/video_engine/vie_channel_manager.cc b/webrtc/video_engine/vie_channel_manager.cc index 85c60e9ee..4c4c66fed 100644 --- a/webrtc/video_engine/vie_channel_manager.cc +++ b/webrtc/video_engine/vie_channel_manager.cc @@ -20,8 +20,8 @@ #include "webrtc/system_wrappers/interface/logging.h" #include "webrtc/video_engine/call_stats.h" #include "webrtc/video_engine/encoder_state_feedback.h" -#include "webrtc/video_engine/payload_router.h" #include "webrtc/video_engine/vie_channel.h" +#include "webrtc/video_engine/vie_channel_group.h" #include "webrtc/video_engine/vie_defines.h" #include "webrtc/video_engine/vie_encoder.h" #include "webrtc/video_engine/vie_remb.h" @@ -29,28 +29,28 @@ namespace webrtc { -ViEChannelManager::ViEChannelManager( - int engine_id, - int number_of_cores, - const Config& config) +ViEChannelManager::ViEChannelManager(int engine_id, + int number_of_cores, + const Config& config) : channel_id_critsect_(CriticalSectionWrapper::CreateCriticalSection()), engine_id_(engine_id), number_of_cores_(number_of_cores), free_channel_ids_(new bool[kViEMaxNumberOfChannels]), free_channel_ids_size_(kViEMaxNumberOfChannels), voice_sync_interface_(NULL), - module_process_thread_(NULL), - engine_config_(config) { + module_process_thread_(NULL) { for (int idx = 0; idx < free_channel_ids_size_; idx++) { free_channel_ids_[idx] = true; } } ViEChannelManager::~ViEChannelManager() { - while (channel_map_.size() > 0) { - ChannelMap::iterator it = channel_map_.begin(); - // DeleteChannel will erase this channel from the map and invalidate |it|. - DeleteChannel(it->first); + while (!channel_groups_.empty()) { + // The channel group is deleted by DeleteChannel when all its channels have + // been deleted. + for (int channel_id : channel_groups_.front()->GetChannelIds()) { + DeleteChannel(channel_id); + } } if (voice_sync_interface_) { @@ -66,8 +66,6 @@ ViEChannelManager::~ViEChannelManager() { free_channel_ids_size_ = 0; } assert(channel_groups_.empty()); - assert(channel_map_.empty()); - assert(vie_encoder_map_.empty()); } void ViEChannelManager::SetModuleProcessThread( @@ -87,53 +85,18 @@ int ViEChannelManager::CreateChannel(int* channel_id, } // Create a new channel group and add this channel. - ChannelGroup* group = new ChannelGroup(module_process_thread_, - channel_group_config); - BitrateAllocator* bitrate_allocator = group->GetBitrateAllocator(); - BitrateController* bitrate_controller = group->GetBitrateController(); - ViEEncoder* vie_encoder = new ViEEncoder( - new_channel_id, number_of_cores_, engine_config_, *module_process_thread_, - bitrate_allocator, bitrate_controller, false); + rtc::scoped_ptr group( + new ChannelGroup(module_process_thread_, channel_group_config)); - RtcpBandwidthObserver* bandwidth_observer = - bitrate_controller->CreateRtcpBandwidthObserver(); - RemoteBitrateEstimator* remote_bitrate_estimator = - group->GetRemoteBitrateEstimator(); - EncoderStateFeedback* encoder_state_feedback = - group->GetEncoderStateFeedback(); - RtcpRttStats* rtcp_rtt_stats = - group->GetCallStats()->rtcp_rtt_stats(); - - if (!(vie_encoder->Init() && - CreateChannelObject(new_channel_id, vie_encoder, bandwidth_observer, - remote_bitrate_estimator, rtcp_rtt_stats, - encoder_state_feedback->GetRtcpIntraFrameObserver(), - true, false))) { - delete vie_encoder; - vie_encoder = NULL; + if (!group->CreateSendChannel(new_channel_id, engine_id_, number_of_cores_, + false)) { ReturnChannelId(new_channel_id); - delete group; return -1; } - // Connect the encoder with the send packet router, to enable sending. - vie_encoder->StartThreadsAndSetSharedMembers( - channel_map_[new_channel_id]->send_payload_router(), - channel_map_[new_channel_id]->vcm_protection_callback()); - // Add ViEEncoder to EncoderFeedBackObserver. - unsigned int ssrc = 0; - int idx = 0; - channel_map_[new_channel_id]->GetLocalSSRC(idx, &ssrc); - encoder_state_feedback->AddEncoder(ssrc, vie_encoder); - std::list ssrcs; - ssrcs.push_back(ssrc); - vie_encoder->SetSsrcs(ssrcs); *channel_id = new_channel_id; group->AddChannel(*channel_id); - channel_groups_.push_back(group); - // Register the channel to receive stats updates. - group->GetCallStats()->RegisterStatsObserver( - channel_map_[new_channel_id]->GetStatsObserver()); + channel_groups_.push_back(group.release()); return 0; } @@ -151,77 +114,27 @@ int ViEChannelManager::CreateChannel(int* channel_id, if (new_channel_id == -1) { return -1; } - BitrateAllocator* bitrate_allocator = channel_group->GetBitrateAllocator(); - BitrateController* bitrate_controller = channel_group->GetBitrateController(); - RtcpBandwidthObserver* bandwidth_observer = - bitrate_controller->CreateRtcpBandwidthObserver(); - RemoteBitrateEstimator* remote_bitrate_estimator = - channel_group->GetRemoteBitrateEstimator(); - EncoderStateFeedback* encoder_state_feedback = - channel_group->GetEncoderStateFeedback(); - RtcpRttStats* rtcp_rtt_stats = - channel_group->GetCallStats()->rtcp_rtt_stats(); - - ViEEncoder* vie_encoder = NULL; if (sender) { - // We need to create a new ViEEncoder. - vie_encoder = - new ViEEncoder(new_channel_id, number_of_cores_, engine_config_, - *module_process_thread_, bitrate_allocator, - bitrate_controller, disable_default_encoder); - if (!(vie_encoder->Init() && - CreateChannelObject( - new_channel_id, - vie_encoder, - bandwidth_observer, - remote_bitrate_estimator, - rtcp_rtt_stats, - encoder_state_feedback->GetRtcpIntraFrameObserver(), - sender, - disable_default_encoder))) { - delete vie_encoder; - vie_encoder = NULL; + if (!channel_group->CreateSendChannel(new_channel_id, engine_id_, + number_of_cores_, + disable_default_encoder)) { + ReturnChannelId(new_channel_id); + return -1; } - // Connect the encoder with the send packet router, to enable sending. - vie_encoder->StartThreadsAndSetSharedMembers( - channel_map_[new_channel_id]->send_payload_router(), - channel_map_[new_channel_id]->vcm_protection_callback()); - - // Register the ViEEncoder to get key frame requests for this channel. - unsigned int ssrc = 0; - int stream_idx = 0; - channel_map_[new_channel_id]->GetLocalSSRC(stream_idx, &ssrc); - encoder_state_feedback->AddEncoder(ssrc, vie_encoder); } else { - vie_encoder = ViEEncoderPtr(original_channel); - assert(vie_encoder); - if (!CreateChannelObject( - new_channel_id, - vie_encoder, - bandwidth_observer, - remote_bitrate_estimator, - rtcp_rtt_stats, - encoder_state_feedback->GetRtcpIntraFrameObserver(), - sender, - disable_default_encoder)) { - vie_encoder = NULL; + if (!channel_group->CreateReceiveChannel(new_channel_id, engine_id_, + original_channel, number_of_cores_, + disable_default_encoder)) { + ReturnChannelId(new_channel_id); + return -1; } } - if (!vie_encoder) { - ReturnChannelId(new_channel_id); - return -1; - } *channel_id = new_channel_id; channel_group->AddChannel(*channel_id); - // Register the channel to receive stats updates. - channel_group->GetCallStats()->RegisterStatsObserver( - channel_map_[new_channel_id]->GetStatsObserver()); return 0; } int ViEChannelManager::DeleteChannel(int channel_id) { - ViEChannel* vie_channel = NULL; - ViEEncoder* vie_encoder = NULL; ChannelGroup* group = NULL; { // Write lock to make sure no one is using the channel. @@ -230,47 +143,11 @@ int ViEChannelManager::DeleteChannel(int channel_id) { // Protect the maps. CriticalSectionScoped cs(channel_id_critsect_); - ChannelMap::iterator c_it = channel_map_.find(channel_id); - if (c_it == channel_map_.end()) { - // No such channel. - return -1; - } - vie_channel = c_it->second; - channel_map_.erase(c_it); - - ReturnChannelId(channel_id); - - // Find the encoder object. - EncoderMap::iterator e_it = vie_encoder_map_.find(channel_id); - assert(e_it != vie_encoder_map_.end()); - vie_encoder = e_it->second; - group = FindGroup(channel_id); - group->GetCallStats()->DeregisterStatsObserver( - vie_channel->GetStatsObserver()); - group->SetChannelRembStatus(channel_id, false, false, vie_channel); - - // If we're owning the encoder, remove the feedback and stop all encoding - // threads and processing. This must be done before deleting the channel. - if (vie_encoder->channel_id() == channel_id) { - group->GetEncoderStateFeedback()->RemoveEncoder(vie_encoder); - vie_encoder->StopThreadsAndRemoveSharedMembers(); - } - - unsigned int remote_ssrc = 0; - vie_channel->GetRemoteSSRC(&remote_ssrc); - group->RemoveChannel(channel_id, remote_ssrc); - - // Check if other channels are using the same encoder. - if (ChannelUsingViEEncoder(channel_id)) { - vie_encoder = NULL; - } else { - // Delete later when we've released the critsect. - } - - // We can't erase the item before we've checked for other channels using - // same ViEEncoder. - vie_encoder_map_.erase(e_it); + if (group == NULL) + return -1; + ReturnChannelId(channel_id); + group->DeleteChannel(channel_id); if (group->Empty()) { channel_groups_.remove(group); @@ -278,15 +155,6 @@ int ViEChannelManager::DeleteChannel(int channel_id) { group = NULL; // Prevent group from being deleted. } } - delete vie_channel; - // Leave the write critsect before deleting the objects. - // Deleting a channel can cause other objects, such as renderers, to be - // deleted, which might take time. - // If statment just to show that this object is not always deleted. - if (vie_encoder) { - LOG(LS_VERBOSE) << "ViEEncoder deleted for channel " << channel_id; - delete vie_encoder; - } // If statment just to show that this object is not always deleted. if (group) { // Delete the group if empty last since the encoder holds a pointer to the @@ -294,7 +162,6 @@ int ViEChannelManager::DeleteChannel(int channel_id) { LOG(LS_VERBOSE) << "Channel group deleted for channel " << channel_id; delete group; } - LOG(LS_VERBOSE) << "Channel deleted " << channel_id; return 0; } @@ -313,9 +180,8 @@ int ViEChannelManager::SetVoiceEngine(VoiceEngine* voice_engine) { } } - for (ChannelMap::iterator it = channel_map_.begin(); it != channel_map_.end(); - ++it) { - it->second->SetVoiceChannel(-1, sync_interface); + for (ChannelGroup* group : channel_groups_) { + group->SetSyncInterface(sync_interface); } if (voice_sync_interface_) { voice_sync_interface_->Release(); @@ -422,66 +288,21 @@ bool ViEChannelManager::GetEstimatedReceiveBandwidth( return true; } -bool ViEChannelManager::CreateChannelObject( - int channel_id, - ViEEncoder* vie_encoder, - RtcpBandwidthObserver* bandwidth_observer, - RemoteBitrateEstimator* remote_bitrate_estimator, - RtcpRttStats* rtcp_rtt_stats, - RtcpIntraFrameObserver* intra_frame_observer, - bool sender, - bool disable_default_encoder) { - PacedSender* paced_sender = vie_encoder->GetPacedSender(); - - ViEChannel* vie_channel = new ViEChannel(channel_id, engine_id_, - number_of_cores_, - engine_config_, - *module_process_thread_, - intra_frame_observer, - bandwidth_observer, - remote_bitrate_estimator, - rtcp_rtt_stats, - paced_sender, - sender, - disable_default_encoder); - if (vie_channel->Init() != 0) { - delete vie_channel; - return false; - } - if (!disable_default_encoder) { - VideoCodec encoder; - if (vie_encoder->GetEncoder(&encoder) != 0) { - delete vie_channel; - return false; - } - if (sender && vie_channel->SetSendCodec(encoder) != 0) { - delete vie_channel; - return false; - } - } - // Store the channel, add it to the channel group and save the vie_encoder. - channel_map_[channel_id] = vie_channel; - vie_encoder_map_[channel_id] = vie_encoder; - return true; -} - ViEChannel* ViEChannelManager::ViEChannelPtr(int channel_id) const { CriticalSectionScoped cs(channel_id_critsect_); - ChannelMap::const_iterator it = channel_map_.find(channel_id); - if (it == channel_map_.end()) { - LOG(LS_ERROR) << "Channel doesn't exist " << channel_id; + ChannelGroup* group = FindGroup(channel_id); + if (group == NULL) return NULL; - } - return it->second; + return group->GetChannel(channel_id); } ViEEncoder* ViEChannelManager::ViEEncoderPtr(int video_channel_id) const { CriticalSectionScoped cs(channel_id_critsect_); - EncoderMap::const_iterator it = vie_encoder_map_.find(video_channel_id); - if (it == vie_encoder_map_.end()) { + ChannelGroup* group = FindGroup(video_channel_id); + if (group == NULL) { return NULL; } - return it->second; + return group->GetEncoder(video_channel_id); } int ViEChannelManager::FreeChannelId() { @@ -517,39 +338,20 @@ ChannelGroup* ViEChannelManager::FindGroup(int channel_id) const { bool ViEChannelManager::ChannelUsingViEEncoder(int channel_id) const { CriticalSectionScoped cs(channel_id_critsect_); - EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); - if (orig_it == vie_encoder_map_.end()) { - // No ViEEncoder for this channel. + ChannelGroup* group = FindGroup(channel_id); + if (group == NULL) { return false; } - - // Loop through all other channels to see if anyone points at the same - // ViEEncoder. - for (EncoderMap::const_iterator comp_it = vie_encoder_map_.begin(); - comp_it != vie_encoder_map_.end(); ++comp_it) { - // Make sure we're not comparing the same channel with itself. - if (comp_it->first != channel_id) { - if (comp_it->second == orig_it->second) { - return true; - } - } - } - return false; + return group->OtherChannelsUsingEncoder(channel_id); } void ViEChannelManager::ChannelsUsingViEEncoder(int channel_id, ChannelList* channels) const { CriticalSectionScoped cs(channel_id_critsect_); - EncoderMap::const_iterator orig_it = vie_encoder_map_.find(channel_id); - - for (ChannelMap::const_iterator c_it = channel_map_.begin(); - c_it != channel_map_.end(); ++c_it) { - EncoderMap::const_iterator comp_it = vie_encoder_map_.find(c_it->first); - assert(comp_it != vie_encoder_map_.end()); - if (comp_it->second == orig_it->second) { - channels->push_back(c_it->second); - } - } + ChannelGroup* group = FindGroup(channel_id); + if (group == NULL) + return; + group->GetChannelsUsingEncoder(channel_id, channels); } ViEChannelManagerScoped::ViEChannelManagerScoped( diff --git a/webrtc/video_engine/vie_channel_manager.h b/webrtc/video_engine/vie_channel_manager.h index e6f6c963e..c4a19b5b4 100644 --- a/webrtc/video_engine/vie_channel_manager.h +++ b/webrtc/video_engine/vie_channel_manager.h @@ -14,17 +14,16 @@ #include #include -#include "webrtc/base/scoped_ptr.h" #include "webrtc/engine_configurations.h" #include "webrtc/typedefs.h" #include "webrtc/video_engine/include/vie_rtp_rtcp.h" -#include "webrtc/video_engine/vie_channel_group.h" #include "webrtc/video_engine/vie_defines.h" #include "webrtc/video_engine/vie_manager_base.h" #include "webrtc/video_engine/vie_remb.h" namespace webrtc { +class ChannelGroup; class Config; class CriticalSectionWrapper; class ProcessThread; @@ -36,8 +35,6 @@ class VoiceEngine; typedef std::list ChannelGroups; typedef std::list ChannelList; -typedef std::map ChannelMap; -typedef std::map EncoderMap; class ViEChannelManager: private ViEManagerBase { friend class ViEChannelManagerScoped; @@ -90,17 +87,6 @@ class ViEChannelManager: private ViEManagerBase { uint32_t* estimated_bandwidth) const; private: - // Creates a channel object connected to |vie_encoder|. Assumed to be called - // protected. - bool CreateChannelObject(int channel_id, - ViEEncoder* vie_encoder, - RtcpBandwidthObserver* bandwidth_observer, - RemoteBitrateEstimator* remote_bitrate_estimator, - RtcpRttStats* rtcp_rtt_stats, - RtcpIntraFrameObserver* intra_frame_observer, - bool sender, - bool disable_default_encoder); - // Used by ViEChannelScoped, forcing a manager user to use scoped. // Returns a pointer to the channel with id 'channel_id'. ViEChannel* ViEChannelPtr(int channel_id) const; @@ -128,8 +114,6 @@ class ViEChannelManager: private ViEManagerBase { int engine_id_; int number_of_cores_; - // TODO(mflodman) Make part of channel group. - ChannelMap channel_map_; bool* free_channel_ids_; int free_channel_ids_size_; @@ -137,12 +121,9 @@ class ViEChannelManager: private ViEManagerBase { std::list channel_groups_; // TODO(mflodman) Make part of channel group. - // Maps Channel id -> ViEEncoder. - EncoderMap vie_encoder_map_; VoEVideoSync* voice_sync_interface_; ProcessThread* module_process_thread_; - const Config& engine_config_; }; class ViEChannelManagerScoped: private ViEManagerScopedBase {