839 lines
26 KiB
C++
839 lines
26 KiB
C++
|
/*
|
||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* vie_base_impl.cc
|
||
|
*/
|
||
|
|
||
|
#include "vie_base_impl.h"
|
||
|
|
||
|
// Defines
|
||
|
#include "engine_configurations.h"
|
||
|
#include "vie_defines.h"
|
||
|
|
||
|
#include "critical_section_wrapper.h"
|
||
|
#include "trace.h"
|
||
|
#include "vie_errors.h"
|
||
|
#include "vie_impl.h"
|
||
|
#include "vie_shared_data.h"
|
||
|
#include "vie_channel.h"
|
||
|
#include "vie_channel_manager.h"
|
||
|
#include "vie_encoder.h"
|
||
|
#include "vie_input_manager.h"
|
||
|
#include "vie_performance_monitor.h"
|
||
|
#include "rtp_rtcp.h"
|
||
|
#include "video_render.h"
|
||
|
#include "video_coding.h"
|
||
|
#include "video_processing.h"
|
||
|
#include "stdio.h"
|
||
|
|
||
|
namespace webrtc
|
||
|
{
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// GetInterface
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViEBase* ViEBase::GetInterface(VideoEngine* videoEngine)
|
||
|
{
|
||
|
if (videoEngine == NULL)
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
VideoEngineImpl* vieImpl = reinterpret_cast<VideoEngineImpl*> (videoEngine);
|
||
|
ViEBaseImpl* vieBaseImpl = vieImpl;
|
||
|
(*vieBaseImpl)++; // Increase ref count
|
||
|
|
||
|
return vieBaseImpl;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Release
|
||
|
//
|
||
|
// Releases the interface, i.e. reduces the reference counter. The number of
|
||
|
// remaining references is returned, -1 if released too many times.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
int ViEBaseImpl::Release()
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, _instanceId,
|
||
|
"ViEBase::Release()");
|
||
|
(*this)--; // Decrease ref count
|
||
|
|
||
|
WebRtc_Word32 refCount = GetCount();
|
||
|
if (refCount < 0)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, _instanceId,
|
||
|
"ViEBase release too many times");
|
||
|
SetLastError(kViEAPIDoesNotExist);
|
||
|
return -1;
|
||
|
}
|
||
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, _instanceId,
|
||
|
"ViEBase reference count: %d", refCount);
|
||
|
return refCount;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Constructor
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViEBaseImpl::ViEBaseImpl() :
|
||
|
_viePerformanceMonitor(0)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
|
||
|
"ViEBaseImpl::ViEBaseImpl() Ctor");
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Destructor
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViEBaseImpl::~ViEBaseImpl()
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
|
||
|
"ViEBaseImpl::ViEBaseImpl() Dtor");
|
||
|
|
||
|
_viePerformanceMonitor.Terminate();
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Init
|
||
|
//
|
||
|
// Must be called before any other API is called.
|
||
|
// This API should also reset the state of the enigne to the original state.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::Init()
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, _instanceId, "Init");
|
||
|
if (IsInitialized())
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, _instanceId,
|
||
|
"Init called twice");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
SetInitialized();
|
||
|
|
||
|
_viePerformanceMonitor.Init();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// SetVoiceEngine
|
||
|
//
|
||
|
// Connects ViE to a VoE instance.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::SetVoiceEngine(VoiceEngine* ptrVoiceEngine)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
|
||
|
__FUNCTION__);
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
if (_channelManager.SetVoiceEngine(ptrVoiceEngine) != 0)
|
||
|
{
|
||
|
SetLastError(kViEBaseVoEFailure);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ============================================================================
|
||
|
// Channel functions
|
||
|
// ============================================================================
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// CreateChannel
|
||
|
//
|
||
|
// Creates a new ViE channel
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::CreateChannel(int& videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
|
||
|
__FUNCTION__);
|
||
|
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_channelManager.CreateChannel(videoChannel) == -1)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: Could not create channel", __FUNCTION__);
|
||
|
videoChannel = -1;
|
||
|
SetLastError(kViEBaseChannelCreationFailed);
|
||
|
return -1;
|
||
|
}
|
||
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel created: %d", __FUNCTION__, videoChannel);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// CreateChannel
|
||
|
//
|
||
|
// Creates a new channel using the same capture device and encoder as
|
||
|
// the original channel.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::CreateChannel(int& videoChannel, int originalChannel)
|
||
|
{
|
||
|
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
|
||
|
if (!cs.Channel(originalChannel))
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - originalChannel does not exist.", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_channelManager.CreateChannel(videoChannel,
|
||
|
originalChannel) == -1)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: Could not create channel", __FUNCTION__);
|
||
|
videoChannel = -1;
|
||
|
SetLastError(kViEBaseChannelCreationFailed);
|
||
|
return -1;
|
||
|
}
|
||
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel created: %d", __FUNCTION__, videoChannel);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// DeleteChannel
|
||
|
//
|
||
|
// Deleted a ViE channel
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::DeleteChannel(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s(%d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
{
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
ViEChannel* vieChannel = cs.Channel(videoChannel);
|
||
|
if (vieChannel == NULL)
|
||
|
{
|
||
|
// No such channel
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel %d doesn't exist", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Deregister the ViEEncoder if no other channel is using it.
|
||
|
ViEEncoder* ptrViEEncoder = cs.Encoder(videoChannel);
|
||
|
if (cs.ChannelUsingViEEncoder(videoChannel) == false)
|
||
|
{
|
||
|
// No other channels using this ViEEncoder.
|
||
|
// Disconnect the channel encoder from possible input.
|
||
|
// capture or file.
|
||
|
ViEInputManagerScoped is(_inputManager);
|
||
|
ViEFrameProviderBase* provider = is.FrameProvider(ptrViEEncoder);
|
||
|
if (provider)
|
||
|
{
|
||
|
provider->DeregisterFrameCallback(ptrViEEncoder);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (_channelManager.DeleteChannel(videoChannel) == -1)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: Could not delete channel %d", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel deleted: %d", __FUNCTION__, videoChannel);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// ConnectAudioChannel
|
||
|
//
|
||
|
// Connects a ViE channel with a VoE channel
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::ConnectAudioChannel(const int videoChannel,
|
||
|
const int audioChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s(%d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
if (cs.Channel(videoChannel) == NULL)
|
||
|
{
|
||
|
// No such channel
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel %d doesn't exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_channelManager.ConnectVoiceChannel(videoChannel, audioChannel) != 0)
|
||
|
{
|
||
|
SetLastError(kViEBaseVoEFailure);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// DisconnectAudioChannel
|
||
|
//
|
||
|
// Disconnects a previously connected ViE and VoE channel pair
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::DisconnectAudioChannel(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s(%d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
if (!IsInitialized())
|
||
|
{
|
||
|
SetLastError(kViENotInitialized);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
||
|
_instanceId);
|
||
|
return -1;
|
||
|
}
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
if (cs.Channel(videoChannel) == NULL)
|
||
|
{
|
||
|
// No such channel
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"%s: channel %d doesn't exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_channelManager.DisconnectVoiceChannel(videoChannel) != 0)
|
||
|
{
|
||
|
SetLastError(kViEBaseVoEFailure);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ============================================================================
|
||
|
// Start and stop
|
||
|
// ============================================================================
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// StartSend
|
||
|
//
|
||
|
// Starts sending on videoChannel and also starts the encoder.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
int ViEBaseImpl::StartSend(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId,
|
||
|
videoChannel),
|
||
|
"%s(channel: %d)", __FUNCTION__, videoChannel);
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
|
||
|
if (ptrViEChannel == NULL)
|
||
|
{
|
||
|
// The channel doesn't exists
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Channel %d does not exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
ViEEncoder* ptrViEEncoder = cs.Encoder(videoChannel);
|
||
|
if (ptrViEEncoder == NULL)
|
||
|
{
|
||
|
assert(false);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Could not find encoder for channel %d", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Make sure we start with a key frame...
|
||
|
ptrViEEncoder->Pause();
|
||
|
WebRtc_Word32 error = ptrViEChannel->StartSend();
|
||
|
if (error != 0)
|
||
|
{
|
||
|
// Restart the encoder, if it was stopped
|
||
|
ptrViEEncoder->Restart();
|
||
|
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Could not start sending on channel %d", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
if (error == kViEBaseAlreadySending)
|
||
|
{
|
||
|
SetLastError(kViEBaseAlreadySending);
|
||
|
}
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Trigger the key frame and restart
|
||
|
ptrViEEncoder->SendKeyFrame();
|
||
|
ptrViEEncoder->Restart();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// StopSend
|
||
|
//
|
||
|
// Stops sending on the channel. This will also stop the encoder for the
|
||
|
// channel, if not shared with still active channels.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
int ViEBaseImpl::StopSend(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
|
||
|
if (ptrViEChannel == NULL)
|
||
|
{
|
||
|
// The channel doesn't exists
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Channel %d does not exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 error = ptrViEChannel->StopSend();
|
||
|
if (error != 0)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Could not stop sending on channel %d", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
if (error == kViEBaseNotSending)
|
||
|
{
|
||
|
SetLastError(kViEBaseNotSending);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// StartReceive
|
||
|
//
|
||
|
// Stops receiving on the channel. This will also start the decoder.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
int ViEBaseImpl::StartReceive(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
|
||
|
if (ptrViEChannel == NULL)
|
||
|
{
|
||
|
// The channel doesn't exists
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Channel %d does not exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
if (ptrViEChannel->Receiving())
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Channel %d already receive.", __FUNCTION__,
|
||
|
videoChannel);
|
||
|
SetLastError(kViEBaseAlreadyReceiving);
|
||
|
return -1;
|
||
|
}
|
||
|
if (ptrViEChannel->StartReceive() != 0)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// StopReceive
|
||
|
//
|
||
|
// Stops receiving on the channel. No decoding will be done.
|
||
|
// ----------------------------------------------------------------------------
|
||
|
int ViEBaseImpl::StopReceive(const int videoChannel)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
||
|
__FUNCTION__, videoChannel);
|
||
|
|
||
|
ViEChannelManagerScoped cs(_channelManager);
|
||
|
ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
|
||
|
if (ptrViEChannel == NULL)
|
||
|
{
|
||
|
// The channel doesn't exists
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
||
|
ViEId(_instanceId, videoChannel),
|
||
|
"%s: Channel %d does not exist", __FUNCTION__, videoChannel);
|
||
|
SetLastError(kViEBaseInvalidChannelId);
|
||
|
return -1;
|
||
|
}
|
||
|
if (ptrViEChannel->StopReceive() != 0)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ============================================================================
|
||
|
// Channel functions
|
||
|
// ============================================================================
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// RegisterObserver
|
||
|
//
|
||
|
// Registers a customer implemented ViE observer
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::RegisterObserver(ViEBaseObserver& observer)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
|
||
|
__FUNCTION__);
|
||
|
if (_viePerformanceMonitor.ViEBaseObserverRegistered())
|
||
|
{
|
||
|
SetLastError(kViEBaseObserverAlreadyRegistered);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return _viePerformanceMonitor.RegisterViEBaseObserver(&observer);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// DeregisterObserver
|
||
|
//
|
||
|
// Deregisters an observer
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::DeregisterObserver()
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId), "%s",
|
||
|
__FUNCTION__);
|
||
|
|
||
|
if (!_viePerformanceMonitor.ViEBaseObserverRegistered())
|
||
|
{
|
||
|
SetLastError(kViEBaseObserverNotRegistered);
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, _instanceId,
|
||
|
"%s No observer registered.", __FUNCTION__);
|
||
|
return -1;
|
||
|
}
|
||
|
return _viePerformanceMonitor.RegisterViEBaseObserver(NULL);
|
||
|
}
|
||
|
|
||
|
// ============================================================================
|
||
|
// Info functions
|
||
|
// ============================================================================
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// GetVersion
|
||
|
//
|
||
|
// Writes version information in 'version'
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::GetVersion(char version[1024])
|
||
|
{
|
||
|
|
||
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"GetVersion(version=?)");
|
||
|
assert(kViEVersionMaxMessageSize == 1024);
|
||
|
|
||
|
if (version == NULL)
|
||
|
{
|
||
|
SetLastError(kViEBaseInvalidArgument);
|
||
|
return (-1);
|
||
|
}
|
||
|
|
||
|
char versionBuf[kViEVersionMaxMessageSize];
|
||
|
char* versionPtr = versionBuf;
|
||
|
|
||
|
WebRtc_Word32 len = 0; // does not include terminating NULL
|
||
|
WebRtc_Word32 accLen = 0;
|
||
|
|
||
|
len = AddViEVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
len = AddBuildInfo(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
#ifdef WEBRTC_EXTERNAL_TRANSPORT
|
||
|
len = AddExternalTransportBuild(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
#endif
|
||
|
|
||
|
len = AddVCMVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
#ifndef WEBRTC_EXTERNAL_TRANSPORT
|
||
|
len = AddSocketModuleVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
#endif
|
||
|
|
||
|
#ifdef WEBRTC_SRTP
|
||
|
len = AddSRTPModuleVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
#endif
|
||
|
|
||
|
len = AddRtpRtcpModuleVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
len = AddVideoCaptureVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
len = AddRenderVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
len = AddVideoProcessingVersion(versionPtr);
|
||
|
if (len == -1)
|
||
|
{
|
||
|
SetLastError(kViEBaseUnknownError);
|
||
|
return -1;
|
||
|
}
|
||
|
versionPtr += len;
|
||
|
accLen += len;
|
||
|
assert(accLen < kViEVersionMaxMessageSize);
|
||
|
|
||
|
memcpy(version, versionBuf, accLen);
|
||
|
version[accLen] = '\0';
|
||
|
|
||
|
WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
||
|
"GetVersion() => %s", version);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddBuildInfo(char* str) const
|
||
|
{
|
||
|
return sprintf(str, "Build: %s\n", BUILDINFO);
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddViEVersion(char* str) const
|
||
|
{
|
||
|
return sprintf(str, "VideoEngine 3.1.0\n");
|
||
|
}
|
||
|
|
||
|
#ifdef WEBRTC_EXTERNAL_TRANSPORT
|
||
|
WebRtc_Word32 ViEBaseImpl::AddExternalTransportBuild(char* str) const
|
||
|
{
|
||
|
return sprintf(str, "External transport build\n");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddModuleVersion(webrtc::Module* module,
|
||
|
char* str) const
|
||
|
{
|
||
|
WebRtc_Word8 version[kViEMaxModuleVersionSize];
|
||
|
WebRtc_UWord32 remainingBufferInBytes(kViEMaxModuleVersionSize);
|
||
|
WebRtc_UWord32 position(0);
|
||
|
if (module && module->Version(version, remainingBufferInBytes, position)
|
||
|
== 0)
|
||
|
{
|
||
|
return sprintf(str, "%s\n", version);
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddVCMVersion(char* str) const
|
||
|
{
|
||
|
webrtc::VideoCodingModule* vcmPtr =
|
||
|
webrtc::VideoCodingModule::Create(_instanceId);
|
||
|
int len = AddModuleVersion(vcmPtr, str);
|
||
|
webrtc::VideoCodingModule::Destroy(vcmPtr);
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddVideoCaptureVersion(char* str) const
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddVideoProcessingVersion(char* str) const
|
||
|
{
|
||
|
webrtc::VideoProcessingModule* videoPtr =
|
||
|
webrtc::VideoProcessingModule::Create(_instanceId);
|
||
|
int len = AddModuleVersion(videoPtr, str);
|
||
|
webrtc::VideoProcessingModule::Destroy(videoPtr);
|
||
|
return len;
|
||
|
}
|
||
|
WebRtc_Word32 ViEBaseImpl::AddRenderVersion(char* str) const
|
||
|
{
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifndef WEBRTC_EXTERNAL_TRANSPORT
|
||
|
WebRtc_Word32 ViEBaseImpl::AddSocketModuleVersion(char* str) const
|
||
|
{
|
||
|
WebRtc_UWord8 numSockThreads(1);
|
||
|
UdpTransport* socketPtr =
|
||
|
UdpTransport::Create(
|
||
|
_instanceId, numSockThreads);
|
||
|
int len = AddModuleVersion(socketPtr, str);
|
||
|
UdpTransport::Destroy(socketPtr);
|
||
|
return len;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef WEBRTC_SRTP
|
||
|
WebRtc_Word32 ViEBaseImpl::AddSRTPModuleVersion(char* str) const
|
||
|
{
|
||
|
SrtpModule* srtpPtr = SrtpModule::CreateSrtpModule(-1);
|
||
|
int len = AddModuleVersion(srtpPtr, str);
|
||
|
SrtpModule::DestroySrtpModule(srtpPtr);
|
||
|
return len;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
WebRtc_Word32 ViEBaseImpl::AddRtpRtcpModuleVersion(char* str) const
|
||
|
{
|
||
|
RtpRtcp* rtpRtcpPtr =
|
||
|
RtpRtcp::CreateRtpRtcp(-1, true);
|
||
|
int len = AddModuleVersion(rtpRtcpPtr, str);
|
||
|
RtpRtcp::DestroyRtpRtcp(rtpRtcpPtr);
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// LastError
|
||
|
//
|
||
|
// Returns the last set error in this ViE instance
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
int ViEBaseImpl::LastError()
|
||
|
{
|
||
|
return LastErrorInternal();
|
||
|
}
|
||
|
|
||
|
} // namespace webrtc
|