Refactored ViEChannelManager ViEInputManager.

Pointers/references and types will come in a future CL.

Review URL: http://webrtc-codereview.appspot.com/317012

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1202 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2011-12-15 10:19:29 +00:00
parent e0e07bbaa0
commit e8be22c192
4 changed files with 1106 additions and 1433 deletions

View File

@ -8,603 +8,448 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* vie_channel_manager.cc
*/
#include "video_engine/vie_channel_manager.h"
#include "vie_channel_manager.h"
#include "engine_configurations.h"
#include "vie_defines.h"
#include "modules/utility/interface/process_thread.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/trace.h"
#include "video_engine/vie_channel.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_encoder.h"
#include "voice_engine/main/interface/voe_video_sync.h"
#include "critical_section_wrapper.h"
#include "trace.h"
#include "vie_channel.h"
#include "vie_encoder.h"
#include "process_thread.h"
namespace webrtc {
// VoiceEngine
#include "voe_video_sync.h"
namespace webrtc
{
ViEChannelManagerScoped::ViEChannelManagerScoped(
const ViEChannelManager& vieChannelManager)
: ViEManagerScopedBase(vieChannelManager)
{
}
ViEChannel* ViEChannelManagerScoped::Channel(int vieChannelId) const
{
return static_cast<const ViEChannelManager*>(vie_manager_)->ViEChannelPtr(
vieChannelId);
}
ViEEncoder* ViEChannelManagerScoped::Encoder(int vieChannelId) const
{
return static_cast<const ViEChannelManager*>(vie_manager_)->ViEEncoderPtr(
vieChannelId);
}
bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channelId) const
{
return (static_cast<const ViEChannelManager*>(vie_manager_))->
ChannelUsingViEEncoder(channelId);
}
// ============================================================================
// VieChannelManager
// ============================================================================
// ----------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------
ViEChannelManager::ViEChannelManager(int engineId,
int numberOfCores,
ViEPerformanceMonitor& viePerformanceMonitor)
: _ptrChannelIdCritsect(CriticalSectionWrapper::CreateCriticalSection()),
_engineId(engineId), _numberOfCores(numberOfCores),
_viePerformanceMonitor(viePerformanceMonitor), _channelMap(),
_freeChannelIds(new bool[kViEMaxNumberOfChannels]),
_freeChannelIdsSize(kViEMaxNumberOfChannels), _vieEncoderMap(),
_voiceSyncInterface(NULL), _voiceEngine(NULL),
_moduleProcessThread(NULL)
{
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engineId),
"ViEChannelManager::ViEChannelManager(engineId: %d) - Constructor",
engineId);
for (int idx = 0; idx < _freeChannelIdsSize; idx++)
{
_freeChannelIds[idx] = true;
ViEChannelManager::ViEChannelManager(
int engine_id,
int number_of_cores,
ViEPerformanceMonitor& vie_performance_monitor)
: channel_id_critsect_(CriticalSectionWrapper::CreateCriticalSection()),
engine_id_(engine_id),
number_of_cores_(number_of_cores),
vie_performance_monitor_(vie_performance_monitor),
free_channel_ids_(new bool[kViEMaxNumberOfChannels]),
free_channel_ids_size_(kViEMaxNumberOfChannels),
voice_sync_interface_(NULL),
voice_engine_(NULL),
module_process_thread_(NULL) {
WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id),
"ViEChannelManager::ViEChannelManager(engine_id: %d)",
engine_id);
for (int idx = 0; idx < free_channel_ids_size_; idx++) {
free_channel_ids_[idx] = true;
}
}
// ----------------------------------------------------------------------------
// SetModuleProcessThread
// Initialize the thread context used by none time critical tasks in video channels.
// ----------------------------------------------------------------------------
void ViEChannelManager::SetModuleProcessThread( ProcessThread& moduleProcessThread)
{
assert(!_moduleProcessThread);
_moduleProcessThread = &moduleProcessThread;
}
// ----------------------------------------------------------------------------
// Destructor
// ----------------------------------------------------------------------------
ViEChannelManager::~ViEChannelManager() {
WEBRTC_TRACE(kTraceMemory, kTraceVideo, ViEId(engine_id_),
"ViEChannelManager Destructor, engine_id: %d", engine_id_);
ViEChannelManager::~ViEChannelManager()
{
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(_engineId),
"ViEChannelManager Destructor, engineId: %d", _engineId);
while (_channelMap.Size() != 0)
{
MapItem* item = _channelMap.First();
const int channelId = item->GetId();
while (channel_map_.Size() != 0) {
MapItem* item = channel_map_.First();
const int channel_id = item->GetId();
item = NULL;
DeleteChannel(channelId);
DeleteChannel(channel_id);
}
if (_voiceSyncInterface)
_voiceSyncInterface->Release();
if (_ptrChannelIdCritsect)
{
delete _ptrChannelIdCritsect;
_ptrChannelIdCritsect = NULL;
if (voice_sync_interface_) {
voice_sync_interface_->Release();
}
if (_freeChannelIds)
{
delete[] _freeChannelIds;
_freeChannelIds = NULL;
_freeChannelIdsSize = 0;
if (channel_id_critsect_) {
delete channel_id_critsect_;
channel_id_critsect_ = NULL;
}
if (free_channel_ids_) {
delete[] free_channel_ids_;
free_channel_ids_ = NULL;
free_channel_ids_size_ = 0;
}
}
// ----------------------------------------------------------------------------
// CreateChannel
//
// Creates a new channel. 'channelId' will be the id of the created channel
// ----------------------------------------------------------------------------
int ViEChannelManager::CreateChannel(int& channelId)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
void ViEChannelManager::SetModuleProcessThread(
ProcessThread& module_process_thread) {
assert(!module_process_thread_);
module_process_thread_ = &module_process_thread;
}
// Get a free id for the new channel
if (GetFreeChannelId(channelId) == false)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"Max number of channels reached: %d", _channelMap.Size());
int ViEChannelManager::CreateChannel(int& channel_id) {
CriticalSectionScoped cs(*channel_id_critsect_);
// Get a free id for the new channel.
if (!GetFreeChannelId(channel_id)) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"Max number of channels reached: %d", channel_map_.Size());
return -1;
}
ViEChannel* vieChannel = new ViEChannel(channelId, _engineId,
_numberOfCores,
*_moduleProcessThread);
if (vieChannel == NULL)
{
ReturnChannelId(channelId);
ViEChannel* vie_channel = new ViEChannel(channel_id, engine_id_,
number_of_cores_,
*module_process_thread_);
if (!vie_channel) {
ReturnChannelId(channel_id);
return -1;
}
if (vieChannel->Init() != 0)
{
// Could not init channel
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s could not init channel", __FUNCTION__, channelId);
ReturnChannelId(channelId);
delete vieChannel;
vieChannel = NULL;
return -1;
}
// There is no ViEEncoder for this channel, create one with default settings
ViEEncoder* vieEncoder = new ViEEncoder(_engineId, channelId,
_numberOfCores,
*_moduleProcessThread);
if (vieEncoder == NULL)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s(videoChannelId: %d) - Could not create a new encoder",
__FUNCTION__, channelId);
delete vieChannel;
if (vie_channel->Init() != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s could not init channel", __FUNCTION__, channel_id);
ReturnChannelId(channel_id);
delete vie_channel;
vie_channel = NULL;
return -1;
}
// Add to the map
if (_vieEncoderMap.Insert(channelId, vieEncoder) != 0)
{
// Could not add to the map
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
// There is no ViEEncoder for this channel, create one with default settings.
ViEEncoder* vie_encoder = new ViEEncoder(engine_id_, channel_id,
number_of_cores_,
*module_process_thread_);
if (!vie_encoder) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s(video_channel_id: %d) - Could not create a new encoder",
__FUNCTION__, channel_id);
delete vie_channel;
return -1;
}
if (vie_encoder_map_.Insert(channel_id, vie_encoder) != 0) {
// Could not add to the map.
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s: Could not add new encoder for video channel %d",
__FUNCTION__, channelId);
delete vieChannel;
delete vieEncoder;
__FUNCTION__, channel_id);
delete vie_channel;
delete vie_encoder;
return -1;
}
_channelMap.Insert(channelId, vieChannel);
// Register the channel at the encoder
RtpRtcp* ptrSendRtpRtcpModule = vieEncoder->SendRtpRtcpModule();
if (vieChannel->RegisterSendRtpRtcpModule(*ptrSendRtpRtcpModule) != 0)
{
channel_map_.Insert(channel_id, vie_channel);
// Register the channel at the encoder.
RtpRtcp* send_rtp_rtcp_module = vie_encoder->SendRtpRtcpModule();
if (vie_channel->RegisterSendRtpRtcpModule(*send_rtp_rtcp_module) != 0) {
assert(false);
_vieEncoderMap.Erase(channelId);
_channelMap.Erase(channelId);
ReturnChannelId(channelId);
delete vieChannel;
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, channelId),
vie_encoder_map_.Erase(channel_id);
channel_map_.Erase(channel_id);
ReturnChannelId(channel_id);
delete vie_channel;
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id),
"%s: Could not register rtp module %d", __FUNCTION__,
channelId);
channel_id);
return -1;
}
return 0;
}
// ----------------------------------------------------------------------------
// CreateChannel
//
// Creates a channel and attaches to an already existing ViEEncoder
// ----------------------------------------------------------------------------
int ViEChannelManager::CreateChannel(int& channel_id, int original_channel) {
CriticalSectionScoped cs(*channel_id_critsect_);
int ViEChannelManager::CreateChannel(int& channelId, int originalChannel)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
// Check that originalChannel already exists
ViEEncoder* vieEncoder = ViEEncoderPtr(originalChannel);
if (vieEncoder == NULL)
{
// The original channel doesn't exist
WEBRTC_TRACE(webrtc::kTraceError,
webrtc::kTraceVideo,
ViEId(_engineId),
"%s: Original channel doesn't exist",
__FUNCTION__,
originalChannel);
// Check that original_channel already exists.
ViEEncoder* vie_encoder = ViEEncoderPtr(original_channel);
if (!vie_encoder) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s: Original channel doesn't exist", __FUNCTION__,
original_channel);
return -1;
}
VideoCodec videoCodec;
if (vieEncoder->GetEncoder(videoCodec) == 0)
{
if (videoCodec.numberOfSimulcastStreams > 0)
{
WEBRTC_TRACE(webrtc::kTraceError,
webrtc::kTraceVideo,
ViEId(_engineId, originalChannel),
VideoCodec video_codec;
if (vie_encoder->GetEncoder(video_codec) == 0) {
if (video_codec.numberOfSimulcastStreams > 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(engine_id_, original_channel),
"%s: Can't share a simulcast encoder",
__FUNCTION__);
return -1;
}
}
// Get a free id for the new channel
if (GetFreeChannelId(channelId) == false)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"Max number of channels reached: %d", _channelMap.Size());
// Get a free id for the new channel.
if (GetFreeChannelId(channel_id) == false) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"Max number of channels reached: %d", channel_map_.Size());
return -1;
}
ViEChannel* vieChannel = new ViEChannel(channelId, _engineId,
_numberOfCores,
*_moduleProcessThread);
if (vieChannel == NULL)
{
ReturnChannelId(channelId);
ViEChannel* vie_channel = new ViEChannel(channel_id, engine_id_,
number_of_cores_,
*module_process_thread_);
if (!vie_channel) {
ReturnChannelId(channel_id);
return -1;
}
if (vieChannel->Init() != 0)
{
// Could not init channel
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s could not init channel", __FUNCTION__, channelId);
ReturnChannelId(channelId);
delete vieChannel;
vieChannel = NULL;
if (vie_channel->Init() != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s could not init channel", __FUNCTION__, channel_id);
ReturnChannelId(channel_id);
delete vie_channel;
vie_channel = NULL;
return -1;
}
if (_vieEncoderMap.Insert(channelId, vieEncoder) != 0)
{
// Could not add to the map
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
if (vie_encoder_map_.Insert(channel_id, vie_encoder) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s: Could not add new encoder for video channel %d",
__FUNCTION__, channelId);
ReturnChannelId(channelId);
delete vieChannel;
__FUNCTION__, channel_id);
ReturnChannelId(channel_id);
delete vie_channel;
return -1;
}
// Set the same encoder settings for the channel as used by the master channel.
// Do this before attaching rtp module to ensure all rtp cihldren has the same codec type
// Set the same encoder settings for the channel as used by the master
// channel. Do this before attaching rtp module to ensure all rtp children has
// the same codec type.
VideoCodec encoder;
if (vieEncoder->GetEncoder(encoder) == 0)
{
vieChannel->SetSendCodec(encoder);
if (vie_encoder->GetEncoder(encoder) == 0) {
vie_channel->SetSendCodec(encoder);
}
_channelMap.Insert(channelId, vieChannel);
channel_map_.Insert(channel_id, vie_channel);
// Register the channel at the encoder
RtpRtcp* ptrSendRtpRtcpModule = vieEncoder->SendRtpRtcpModule();
if (vieChannel->RegisterSendRtpRtcpModule(*ptrSendRtpRtcpModule) != 0)
{
// Register the channel at the encoder.
RtpRtcp* send_rtp_rtcp_module = vie_encoder->SendRtpRtcpModule();
if (vie_channel->RegisterSendRtpRtcpModule(*send_rtp_rtcp_module) != 0) {
assert(false);
_vieEncoderMap.Erase(channelId);
_channelMap.Erase(channelId);
ReturnChannelId(channelId);
delete vieChannel;
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, channelId),
vie_encoder_map_.Erase(channel_id);
channel_map_.Erase(channel_id);
ReturnChannelId(channel_id);
delete vie_channel;
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id),
"%s: Could not register rtp module %d", __FUNCTION__,
channelId);
channel_id);
return -1;
}
return 0;
}
// ----------------------------------------------------------------------------
// DeleteChannel
// ----------------------------------------------------------------------------
int ViEChannelManager::DeleteChannel(int channelId)
int ViEChannelManager::DeleteChannel(int channel_id) {
ViEChannel* vie_channel = NULL;
ViEEncoder* vie_encoder = NULL;
{
ViEChannel* vieChannel = NULL;
ViEEncoder* vieEncoder = NULL;
{
// Write lock to make sure no one is using the channel
// Write lock to make sure no one is using the channel.
ViEManagerWriteScoped wl(*this);
// Protect the map
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
// Protect the map.
CriticalSectionScoped cs(*channel_id_critsect_);
MapItem* mapItem = _channelMap.Find(channelId);
if (mapItem == NULL)
{
// No such channel
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s Channel doesn't exist: %d", __FUNCTION__, channelId);
MapItem* map_item = channel_map_.Find(channel_id);
if (!map_item) {
// No such channel.
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s Channel doesn't exist: %d", __FUNCTION__, channel_id);
return -1;
}
vieChannel = reinterpret_cast<ViEChannel*> (mapItem->GetItem());
_channelMap.Erase(mapItem);
// Deregister the channel from the ViEEncoder to stop the media flow
vieChannel->DeregisterSendRtpRtcpModule();
ReturnChannelId(channelId);
vie_channel = reinterpret_cast<ViEChannel*>(map_item->GetItem());
channel_map_.Erase(map_item);
// Deregister the channel from the ViEEncoder to stop the media flow.
vie_channel->DeregisterSendRtpRtcpModule();
ReturnChannelId(channel_id);
// Find the encoder object
mapItem = _vieEncoderMap.Find(channelId);
if (mapItem == NULL)
{
// Find the encoder object.
map_item = vie_encoder_map_.Find(channel_id);
if (!map_item) {
assert(false);
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId),
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_),
"%s ViEEncoder not found for channel %d", __FUNCTION__,
channelId);
channel_id);
return -1;
}
// Get the ViEEncoder item
vieEncoder = reinterpret_cast<ViEEncoder*> (mapItem->GetItem());
// Check if other channels are using the same encoder
if (ChannelUsingViEEncoder(channelId))
{
// Don't delete the ViEEncoder, at least on other channel is using it.
WEBRTC_TRACE(
webrtc::kTraceInfo,
webrtc::kTraceVideo,
ViEId(_engineId),
// Get the ViEEncoder item.
vie_encoder = reinterpret_cast<ViEEncoder*>(map_item->GetItem());
// Check if other channels are using the same encoder.
if (ChannelUsingViEEncoder(channel_id)) {
// Don't delete the ViEEncoder, at least one other channel is using it.
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_),
"%s ViEEncoder removed from map for channel %d, not deleted",
__FUNCTION__, channelId);
vieEncoder = NULL;
} else
{
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId),
__FUNCTION__, channel_id);
vie_encoder = NULL;
} else {
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_),
"%s ViEEncoder deleted for channel %d", __FUNCTION__,
channelId);
// Delete later when we've released the critsect
channel_id);
// Delete later when we've released the critsect.
}
// We can't erase the item before we've checked for other channels using same ViEEncoder
_vieEncoderMap.Erase(mapItem);
// We can't erase the item before we've checked for other channels using
// same ViEEncoder.
vie_encoder_map_.Erase(map_item);
}
// Leave the write critsect before deleting the objects.
// Deleting a channel can cause other objects, such as renderers, to be deleted and might take time
if (vieEncoder)
{
delete vieEncoder;
// Deleting a channel can cause other objects, such as renderers, to be
// deleted, which might take time.
if (vie_encoder) {
delete vie_encoder;
}
delete vieChannel;
delete vie_channel;
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_engineId),
"%s Channel %d deleted", __FUNCTION__, channelId);
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_),
"%s Channel %d deleted", __FUNCTION__, channel_id);
return 0;
}
// ----------------------------------------------------------------------------
// Channel
//
// Returns a pointer to the channel with id 'channelId'
// ----------------------------------------------------------------------------
int ViEChannelManager::SetVoiceEngine(VoiceEngine* voice_engine) {
// Write lock to make sure no one is using the channel.
ViEManagerWriteScoped wl(*this);
ViEChannel* ViEChannelManager::ViEChannelPtr(int channelId) const
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
MapItem* mapItem = _channelMap.Find(channelId);
if (mapItem == NULL)
{
// No such channel
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s Channel doesn't exist: %d", __FUNCTION__, channelId);
CriticalSectionScoped cs(*channel_id_critsect_);
VoEVideoSync* sync_interface = NULL;
if (voice_engine) {
// Get new sync interface.
sync_interface = VoEVideoSync::GetInterface(voice_engine);
if (!sync_interface) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s Can't get audio sync interface from VoiceEngine.",
__FUNCTION__);
if (sync_interface) {
sync_interface->Release();
}
return -1;
}
}
for (MapItem* item = channel_map_.First(); item != NULL;
item = channel_map_.Next(item)) {
ViEChannel* channel = static_cast<ViEChannel*>(item->GetItem());
assert(channel);
channel->SetVoiceChannel(-1, sync_interface);
}
if (voice_sync_interface_) {
voice_sync_interface_->Release();
}
voice_engine_ = voice_engine;
voice_sync_interface_ = sync_interface;
return 0;
}
int ViEChannelManager::ConnectVoiceChannel(int channel_id,
int audio_channel_id) {
CriticalSectionScoped cs(*channel_id_critsect_);
if (!voice_sync_interface_) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id),
"No VoE set");
return -1;
}
ViEChannel* channel = ViEChannelPtr(channel_id);
if (!channel) {
return -1;
}
return channel->SetVoiceChannel(audio_channel_id, voice_sync_interface_);
}
int ViEChannelManager::DisconnectVoiceChannel(int channel_id) {
CriticalSectionScoped cs(*channel_id_critsect_);
ViEChannel* channel = ViEChannelPtr(channel_id);
if (channel) {
channel->SetVoiceChannel(-1, NULL);
return 0;
}
return -1;
}
VoiceEngine* ViEChannelManager::GetVoiceEngine() {
CriticalSectionScoped cs(*channel_id_critsect_);
return voice_engine_;
}
ViEChannel* ViEChannelManager::ViEChannelPtr(int channel_id) const {
CriticalSectionScoped cs(*channel_id_critsect_);
MapItem* map_item = channel_map_.Find(channel_id);
if (!map_item) {
// No such channel.
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_),
"%s Channel doesn't exist: %d", __FUNCTION__, channel_id);
return NULL;
}
ViEChannel* vieChannel = reinterpret_cast<ViEChannel*> (mapItem->GetItem());
return vieChannel;
ViEChannel* vie_channel = reinterpret_cast<ViEChannel*>(map_item->GetItem());
return vie_channel;
}
// ----------------------------------------------------------------------------
// GetChannels
//
// Adds all channels to channelMap
// ----------------------------------------------------------------------------
void ViEChannelManager::GetViEChannels(MapWrapper& channelMap)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
if (channelMap.Size() == 0)
{
// No channels
void ViEChannelManager::GetViEChannels(MapWrapper& channel_map) {
CriticalSectionScoped cs(*channel_id_critsect_);
if (channel_map.Size() == 0) {
return;
}
// Add all items to 'channelMap'
for (MapItem* item = _channelMap.First(); item != NULL; item
= _channelMap.Next(item))
{
channelMap.Insert(item->GetId(), item->GetItem());
// Add all items to 'channelMap'.
for (MapItem* item = channel_map_.First(); item != NULL;
item = channel_map_.Next(item)) {
channel_map.Insert(item->GetId(), item->GetItem());
}
return;
}
// ----------------------------------------------------------------------------
// ViEEncoderPtr
//
// Gets the ViEEncoder used as input for videoChannelId
// ----------------------------------------------------------------------------
ViEEncoder* ViEChannelManager::ViEEncoderPtr(int videoChannelId) const
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
MapItem* mapItem = _vieEncoderMap.Find(videoChannelId);
if (mapItem == NULL)
{
// No ViEEncoder for this channel...
ViEEncoder* ViEChannelManager::ViEEncoderPtr(int video_channel_id) const {
CriticalSectionScoped cs(*channel_id_critsect_);
MapItem* map_item = vie_encoder_map_.Find(video_channel_id);
if (!map_item) {
return NULL;
}
ViEEncoder* vieEncoder = static_cast<ViEEncoder*> (mapItem->GetItem());
return vieEncoder;
ViEEncoder* vie_encoder = static_cast<ViEEncoder*>(map_item->GetItem());
return vie_encoder;
}
// ----------------------------------------------------------------------------
// GetFreeChannelId
//
// Returns true if we found a new channel id, freeChannelId, false otherwise
// ----------------------------------------------------------------------------
bool ViEChannelManager::GetFreeChannelId(int& freeChannelId)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
bool ViEChannelManager::GetFreeChannelId(int& free_channel_id) {
CriticalSectionScoped cs(*channel_id_critsect_);
int idx = 0;
while (idx < _freeChannelIdsSize)
{
if (_freeChannelIds[idx] == true)
{
// We've found a free id, allocate it and return
_freeChannelIds[idx] = false;
freeChannelId = idx + kViEChannelIdBase;
while (idx < free_channel_ids_size_) {
if (free_channel_ids_[idx] == true) {
// We've found a free id, allocate it and return.
free_channel_ids_[idx] = false;
free_channel_id = idx + kViEChannelIdBase;
return true;
}
idx++;
}
// No free channel id
freeChannelId = -1;
// No free channel id.
free_channel_id = -1;
return false;
}
// ----------------------------------------------------------------------------
// ReturnChannelID
//
// Returns a previously allocated channel id
// ----------------------------------------------------------------------------
void ViEChannelManager::ReturnChannelId(int channelId)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
assert(channelId < kViEMaxNumberOfChannels+kViEChannelIdBase && channelId>=kViEChannelIdBase);
_freeChannelIds[channelId - kViEChannelIdBase] = true;
void ViEChannelManager::ReturnChannelId(int channel_id) {
CriticalSectionScoped cs(*channel_id_critsect_);
assert(channel_id < kViEMaxNumberOfChannels + kViEChannelIdBase &&
channel_id >= kViEChannelIdBase);
free_channel_ids_[channel_id - kViEChannelIdBase] = true;
}
// ----------------------------------------------------------------------------
// ChannelUsingViEEncoder
//
// Returns true if at least one nother channel is using the same encoder
// ----------------------------------------------------------------------------
bool ViEChannelManager::ChannelUsingViEEncoder(int channelId) const
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
MapItem* channelItem = _vieEncoderMap.Find(channelId);
if (channelItem == NULL)
{
// No ViEEncoder for this channel...
bool ViEChannelManager::ChannelUsingViEEncoder(int channel_id) const {
CriticalSectionScoped cs(*channel_id_critsect_);
MapItem* channel_item = vie_encoder_map_.Find(channel_id);
if (!channel_item) {
// No ViEEncoder for this channel.
return false;
}
ViEEncoder* channelEncoder =
static_cast<ViEEncoder*> (channelItem->GetItem());
ViEEncoder* channel_encoder =
static_cast<ViEEncoder*>(channel_item->GetItem());
// Loop through all other channels to see if anyone points at the same ViEEncoder
MapItem* mapItem = _vieEncoderMap.First();
while (mapItem)
{
if (mapItem->GetId() != channelId)
{
if (channelEncoder == static_cast<ViEEncoder*> (mapItem->GetItem()))
{
// We've found another channel using the same ViEEncoder
// Loop through all other channels to see if anyone points at the same
// ViEEncoder.
MapItem* map_item = vie_encoder_map_.First();
while (map_item) {
if (map_item->GetId() != channel_id) {
if (channel_encoder == static_cast<ViEEncoder*>(map_item->GetItem())) {
return true;
}
}
mapItem = _vieEncoderMap.Next(mapItem);
map_item = vie_encoder_map_.Next(map_item);
}
return false;
}
// ----------------------------------------------------------------------------
// SetVoiceEngine
//
// Set the voice engine instance to be used by all video channels. We are interested in the voice engine sync interfaces
// ----------------------------------------------------------------------------
int ViEChannelManager::SetVoiceEngine(VoiceEngine* voiceEngine)
{
// Write lock to make sure no one is using the channel
ViEManagerWriteScoped wl(*this);
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
VoEVideoSync* syncInterface = NULL;
if (voiceEngine)
{
// Get new sync interface;
syncInterface = VoEVideoSync::GetInterface(voiceEngine);
if (!syncInterface)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
"%s Can't get audio sync interface from VoiceEngine.",
__FUNCTION__);
if (syncInterface)
{
syncInterface->Release();
}
return -1;
}
ViEChannelManagerScoped::ViEChannelManagerScoped(
const ViEChannelManager& vie_channel_manager)
: ViEManagerScopedBase(vie_channel_manager) {
}
for (MapItem* item = _channelMap.First(); item != NULL; item
= _channelMap.Next(item))
{
ViEChannel* channel = static_cast<ViEChannel*> (item->GetItem());
assert(channel);
channel->SetVoiceChannel(-1, syncInterface);
ViEChannel* ViEChannelManagerScoped::Channel(int vie_channel_id) const {
return static_cast<const ViEChannelManager*>(vie_manager_)->ViEChannelPtr(
vie_channel_id);
}
if (_voiceSyncInterface)
{
_voiceSyncInterface->Release();
}
_voiceEngine = voiceEngine;
_voiceSyncInterface = syncInterface;
return 0;
}
VoiceEngine* ViEChannelManager::GetVoiceEngine()
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
return _voiceEngine;
ViEEncoder* ViEChannelManagerScoped::Encoder(int vie_channel_id) const {
return static_cast<const ViEChannelManager*>(vie_manager_)->ViEEncoderPtr(
vie_channel_id);
}
// ----------------------------------------------------------------------------
// ConnectVoiceChannel
//
// Enables lip sync of the channel.
// ----------------------------------------------------------------------------
int ViEChannelManager::ConnectVoiceChannel(int channelId, int audioChannelId)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
if (_voiceSyncInterface == NULL)
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId, channelId),
"No VoE set");
return -1;
}
ViEChannel* channel = ViEChannelPtr(channelId);
if (!channel)
{
return -1;
}
return channel->SetVoiceChannel(audioChannelId, _voiceSyncInterface);
bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channel_id) const {
return (static_cast<const ViEChannelManager*>(vie_manager_))->
ChannelUsingViEEncoder(channel_id);
}
// ----------------------------------------------------------------------------
// DisconnectVoiceChannel
//
// Disables lip sync of the channel.
// ----------------------------------------------------------------------------
int ViEChannelManager::DisconnectVoiceChannel(int channelId)
{
CriticalSectionScoped cs(*_ptrChannelIdCritsect);
ViEChannel* channel = ViEChannelPtr(channelId);
if (channel)
{
channel->SetVoiceChannel(-1, NULL);
return 0;
} else
{
return -1;
}
}
} // namespace webrtc

View File

@ -8,95 +8,106 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* vie_channel_manager.h
*/
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
#define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
#ifndef WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_CHANNEL_MANAGER_H_
#define WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_CHANNEL_MANAGER_H_
// Defines
#include "engine_configurations.h"
#include "vie_defines.h"
#include "system_wrappers/interface/map_wrapper.h"
#include "typedefs.h"
#include "map_wrapper.h"
#include "vie_manager_base.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_manager_base.h"
namespace webrtc {
namespace webrtc
{
class CriticalSectionWrapper;
//class VoiceEngine;
class ProcessThread;
class ViEChannel;
class VoEVideoSync;
class ViEPerformanceMonitor;
class ViEEncoder;
class ViEPerformanceMonitor;
class VoEVideoSync;
class VoiceEngine;
// ------------------------------------------------------------------
// ViEChannelManager
// ------------------------------------------------------------------
class ViEChannelManager: private ViEManagerBase
{
class ViEChannelManager: private ViEManagerBase {
friend class ViEChannelManagerScoped;
public:
ViEChannelManager(int engineId, int numberOfCores,
ViEPerformanceMonitor& viePerformanceMonitor);
ViEChannelManager(int engine_id,
int number_of_cores,
ViEPerformanceMonitor& vie_performance_monitor);
~ViEChannelManager();
void SetModuleProcessThread(ProcessThread& moduleProcessThread);
int CreateChannel(int& channelId);
int CreateChannel(int& channelId, int originalChannel);
int DeleteChannel(int channelId);
int SetVoiceEngine(VoiceEngine* voiceEngine);
int ConnectVoiceChannel(int channelId, int audioChannelId);
int DisconnectVoiceChannel(int channelId);
void SetModuleProcessThread(ProcessThread& module_process_thread);
// Creates a new channel. 'channelId' will be the id of the created channel.
int CreateChannel(int& channel_id);
// Creates a channel and attaches to an already existing ViEEncoder.
int CreateChannel(int& channel_id, int original_channel);
// Deletes a channel.
int DeleteChannel(int channel_id);
// Set the voice engine instance to be used by all video channels.
int SetVoiceEngine(VoiceEngine* voice_engine);
// Enables lip sync of the channel.
int ConnectVoiceChannel(int channel_id, int audio_channel_id);
// Disables lip sync of the channel.
int DisconnectVoiceChannel(int channel_id);
VoiceEngine* GetVoiceEngine();
private:
// Used by ViEChannelScoped, forcing a manager user to use scoped
ViEChannel* ViEChannelPtr(int channelId) const;
void GetViEChannels(MapWrapper& channelMap);
// Used by ViEChannelScoped, forcing a manager user to use scoped.
// Returns a pointer to the channel with id 'channelId'.
ViEChannel* ViEChannelPtr(int channel_id) const;
// Methods used by ViECaptureScoped and ViEEncoderScoped
ViEEncoder* ViEEncoderPtr(int videoChannelId) const;
// Adds all channels to channel_map.
void GetViEChannels(MapWrapper& channel_map);
bool GetFreeChannelId(int& freeChannelId);
void ReturnChannelId(int channelId);
// Methods used by ViECaptureScoped and ViEEncoderScoped.
// Gets the ViEEncoder used as input for video_channel_id
ViEEncoder* ViEEncoderPtr(int video_channel_id) const;
// Returns true if at least one other channels uses the same ViEEncoder as channelId
bool ChannelUsingViEEncoder(int channelId) const;
// Returns true if we found a new channel id, free_channel_id, false
// otherwise.
bool GetFreeChannelId(int& free_channel_id);
// Members
CriticalSectionWrapper* _ptrChannelIdCritsect; // protecting _channelMap and _freeChannelIds
int _engineId;
int _numberOfCores;
ViEPerformanceMonitor& _viePerformanceMonitor;
MapWrapper _channelMap;
bool* _freeChannelIds;
int _freeChannelIdsSize;
// Encoder
MapWrapper _vieEncoderMap; // Channel id -> ViEEncoder
VoEVideoSync* _voiceSyncInterface;
VoiceEngine* _voiceEngine;
ProcessThread* _moduleProcessThread;
// Returns a previously allocated channel id.
void ReturnChannelId(int channel_id);
// Returns true if at least one other channels uses the same ViEEncoder as
// channel_id.
bool ChannelUsingViEEncoder(int channel_id) const;
// Protects channel_map_ and free_channel_ids_.
CriticalSectionWrapper* channel_id_critsect_;
int engine_id_;
int number_of_cores_;
ViEPerformanceMonitor& vie_performance_monitor_;
MapWrapper channel_map_;
bool* free_channel_ids_;
int free_channel_ids_size_;
// Maps Channel id -> ViEEncoder.
MapWrapper vie_encoder_map_;
VoEVideoSync* voice_sync_interface_;
VoiceEngine* voice_engine_;
ProcessThread* module_process_thread_;
};
// ------------------------------------------------------------------
// ViEChannelManagerScoped
// ------------------------------------------------------------------
class ViEChannelManagerScoped: private ViEManagerScopedBase
{
class ViEChannelManagerScoped: private ViEManagerScopedBase {
public:
ViEChannelManagerScoped(const ViEChannelManager& vieChannelManager);
ViEChannel* Channel(int vieChannelId) const;
ViEEncoder* Encoder(int vieChannelId) const;
explicit ViEChannelManagerScoped(
const ViEChannelManager& vie_channel_manager);
ViEChannel* Channel(int vie_channel_id) const;
ViEEncoder* Encoder(int vie_channel_id) const;
// Returns true if at lease one other channels uses the same ViEEncoder as channelId
bool ChannelUsingViEEncoder(int channelId) const;
// Returns true if at lease one other channels uses the same ViEEncoder as
// channel_id.
bool ChannelUsingViEEncoder(int channel_id) const;
};
} // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_CHANNEL_MANAGER_H_
#endif // WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_

File diff suppressed because it is too large Load Diff

View File

@ -8,114 +8,135 @@
* be found in the AUTHORS file in the root of the source tree.
*/
/*
* vie_input_manager.h
*/
#ifndef WEBRTC_VIDEO_ENGINE_VIE_INPUT_MANAGER_H_
#define WEBRTC_VIDEO_ENGINE_VIE_INPUT_MANAGER_H_
#ifndef WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_INPUT_MANAGER_H_
#define WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_INPUT_MANAGER_H_
#include "vie_defines.h"
#include "modules/video_capture/main/interface/video_capture.h"
#include "system_wrappers/interface/map_wrapper.h"
#include "typedefs.h"
#include "map_wrapper.h"
#include "video_capture.h"
#include "vie_manager_base.h"
#include "vie_frame_provider_base.h"
#include "vie_capture.h"
class ViEExternalCapture;
#include "video_engine/main/interface/vie_capture.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_frame_provider_base.h"
#include "video_engine/vie_manager_base.h"
namespace webrtc {
class CriticalSectionWrapper;
class ProcessThread;
class RWLockWrapper;
class ViECapturer;
class ViEExternalCapture;
class ViEFilePlayer;
class VoiceEngine;
class ViEInputManager: private ViEManagerBase
{
class ViEInputManager : private ViEManagerBase {
friend class ViEInputManagerScoped;
public:
ViEInputManager(int engineId);
explicit ViEInputManager(int engine_id);
~ViEInputManager();
void SetModuleProcessThread(ProcessThread& moduleProcessThread);
void SetModuleProcessThread(ProcessThread& module_process_thread);
// Capture device information
// Returns number of capture devices.
int NumberOfCaptureDevices();
int GetDeviceName(WebRtc_UWord32 deviceNumber,
WebRtc_UWord8* deviceNameUTF8,
WebRtc_UWord32 deviceNameLength,
WebRtc_UWord8* deviceUniqueIdUTF8,
WebRtc_UWord32 deviceUniqueIdUTF8Length);
int NumberOfCaptureCapabilities(const WebRtc_UWord8* deviceUniqueIdUTF8);
int GetCaptureCapability(const WebRtc_UWord8* deviceUniqueIdUTF8,
const WebRtc_UWord32 deviceCapabilityNumber,
// Gets name and id for a capture device.
int GetDeviceName(WebRtc_UWord32 device_number,
WebRtc_UWord8* device_nameUTF8,
WebRtc_UWord32 device_name_length,
WebRtc_UWord8* device_unique_idUTF8,
WebRtc_UWord32 device_unique_idUTF8Length);
// Returns the number of capture capabilities for a specified device.
int NumberOfCaptureCapabilities(const WebRtc_UWord8* device_unique_idUTF8);
// Gets a specific capability for a capture device.
int GetCaptureCapability(const WebRtc_UWord8* device_unique_idUTF8,
const WebRtc_UWord32 device_capability_number,
CaptureCapability& capability);
int DisplayCaptureSettingsDialogBox(const WebRtc_UWord8* deviceUniqueIdUTF8,
const WebRtc_UWord8* dialogTitleUTF8,
void* parentWindow,
// Show OS specific Capture settings.
int DisplayCaptureSettingsDialogBox(const WebRtc_UWord8* device_unique_idUTF8,
const WebRtc_UWord8* dialog_titleUTF8,
void* parent_window,
WebRtc_UWord32 positionX,
WebRtc_UWord32 positionY);
int GetOrientation(const WebRtc_UWord8* deviceUniqueIdUTF8,
int GetOrientation(const WebRtc_UWord8* device_unique_idUTF8,
RotateCapturedFrame& orientation);
// Create/delete Capture device settings
// Return zero on success. A ViEError on failure.
int CreateCaptureDevice(const WebRtc_UWord8* deviceUniqueIdUTF8,
const WebRtc_UWord32 deviceUniqueIdUTF8Length,
int& captureId);
int CreateCaptureDevice(VideoCaptureModule& captureModule,
int& captureId);
int CreateExternalCaptureDevice(ViEExternalCapture*& externalCapture,
int& captureId);
int DestroyCaptureDevice(int captureId);
// Creates a capture module for the specified capture device and assigns
// a capture device id for the device.
// Return zero on success, ViEError on failure.
int CreateCaptureDevice(const WebRtc_UWord8* device_unique_idUTF8,
const WebRtc_UWord32 device_unique_idUTF8Length,
int& capture_id);
int CreateCaptureDevice(VideoCaptureModule& capture_module,
int& capture_id);
int CreateExternalCaptureDevice(ViEExternalCapture*& external_capture,
int& capture_id);
int DestroyCaptureDevice(int capture_id);
int CreateFilePlayer(const WebRtc_Word8* fileNameUTF8, const bool loop,
const webrtc::FileFormats fileFormat, VoiceEngine* vePtr,
int& fileId);
int DestroyFilePlayer(int fileId);
int CreateFilePlayer(const WebRtc_Word8* file_nameUTF8, const bool loop,
const FileFormats file_format,
VoiceEngine* voe_ptr,
int& file_id);
int DestroyFilePlayer(int file_id);
private:
bool GetFreeCaptureId(int& freecaptureId);
void ReturnCaptureId(int captureId);
bool GetFreeFileId(int& freeFileId);
void ReturnFileId(int fileId);
// Gets and allocates a free capture device id. Assumed protected by caller.
bool GetFreeCaptureId(int& freecapture_id);
ViEFrameProviderBase* ViEFrameProvider(const ViEFrameCallback*
captureObserver) const;
ViEFrameProviderBase* ViEFrameProvider(int providerId) const;
// Frees a capture id assigned in GetFreeCaptureId.
void ReturnCaptureId(int capture_id);
ViECapturer* ViECapturePtr(int captureId) const;
void GetViECaptures(MapWrapper& vieCaptureMap);
// Gets and allocates a free file id. Assumed protected by caller.
bool GetFreeFileId(int& free_file_id);
ViEFilePlayer* ViEFilePlayerPtr(int fileId) const;
// Frees a file id assigned in GetFreeFileId.
void ReturnFileId(int file_id);
// Members
int _engineId;
CriticalSectionWrapper& _mapCritsect;
MapWrapper _vieFrameProviderMap;
// Gets the ViEFrameProvider for this capture observer.
ViEFrameProviderBase* ViEFrameProvider(
const ViEFrameCallback* capture_observer) const;
// Capture devices
VideoCaptureModule::DeviceInfo* _ptrCaptureDeviceInfo;
int _freeCaptureDeviceId[kViEMaxCaptureDevices];
//File Players
int _freeFileId[kViEMaxFilePlayers];
//uses
ProcessThread* _moduleProcessThread;
// Gets the ViEFrameProvider for this capture observer.
ViEFrameProviderBase* ViEFrameProvider(int provider_id) const;
// Gets the ViECapturer for the capture device id.
ViECapturer* ViECapturePtr(int capture_id) const;
// Gets the the entire map with GetViECaptures.
void GetViECaptures(MapWrapper& vie_capture_map);
// Gets the ViEFilePlayer for this file_id.
ViEFilePlayer* ViEFilePlayerPtr(int file_id) const;
int engine_id_;
CriticalSectionWrapper& map_cs_;
MapWrapper vie_frame_provider_map_;
// Capture devices.
VideoCaptureModule::DeviceInfo* capture_device_info_;
int free_capture_device_id_[kViEMaxCaptureDevices];
// File Players.
int free_file_id_[kViEMaxFilePlayers];
ProcessThread* module_process_thread_;
};
class ViEInputManagerScoped: private ViEManagerScopedBase
{
// Provides protected access to ViEInputManater.
class ViEInputManagerScoped: private ViEManagerScopedBase {
public:
ViEInputManagerScoped(const ViEInputManager& vieInputManager);
explicit ViEInputManagerScoped(const ViEInputManager& vie_input_manager);
ViECapturer* Capture(int captureId) const;
ViEFilePlayer* FilePlayer(int fileId) const;
ViEFrameProviderBase* FrameProvider(int providerId) const;
ViECapturer* Capture(int capture_id) const;
ViEFilePlayer* FilePlayer(int file_id) const;
ViEFrameProviderBase* FrameProvider(int provider_id) const;
ViEFrameProviderBase* FrameProvider(const ViEFrameCallback*
captureObserver) const;
capture_observer) const;
};
} // namespace webrtc
#endif // WEBRTC_VIDEO_ENGINE_MAIN_SOURCE_VIE_INPUT_MANAGER_H_
#endif // WEBRTC_VIDEO_ENGINE_VIE_INPUT_MANAGER_H_