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:
parent
a32f064e97
commit
a50e6f073d
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user