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
This commit is contained in:
stefan@webrtc.org 2015-03-09 10:06:40 +00:00
parent a32f064e97
commit a50e6f073d
5 changed files with 311 additions and 286 deletions

View File

@ -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) {

View File

@ -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<ViEEncoder> 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<unsigned int> 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<ViEChannel> 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<int> ChannelGroup::GetChannelIds() const {
std::vector<int> 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();
}

View File

@ -11,7 +11,10 @@
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_GROUP_H_
#define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_GROUP_H_
#include <list>
#include <map>
#include <set>
#include <vector>
#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<ViEChannel*> 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<int> 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<int, ViEChannel*> ChannelMap;
typedef std::set<int> ChannelSet;
typedef std::map<int, ViEEncoder*> 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<VieRemb> remb_;
rtc::scoped_ptr<BitrateAllocator> bitrate_allocator_;
@ -66,6 +98,9 @@ class ChannelGroup : public BitrateObserver {
rtc::scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
rtc::scoped_ptr<EncoderStateFeedback> 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<Config> own_config_;

View File

@ -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<ChannelGroup> 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<unsigned int> 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(

View File

@ -14,17 +14,16 @@
#include <list>
#include <map>
#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<ChannelGroup*> ChannelGroups;
typedef std::list<ViEChannel*> ChannelList;
typedef std::map<int, ViEChannel*> ChannelMap;
typedef std::map<int, ViEEncoder*> 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<ChannelGroup*> 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 {