1127 lines
41 KiB
C++
1127 lines
41 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_network_impl.cpp
|
|
*/
|
|
|
|
#include "vie_network_impl.h"
|
|
|
|
// Defines
|
|
#include "engine_configurations.h"
|
|
#include "vie_defines.h"
|
|
|
|
// WebRTC include
|
|
#include "vie_errors.h"
|
|
#include "trace.h"
|
|
#include "vie_impl.h"
|
|
#include "vie_channel.h"
|
|
#include "vie_channel_manager.h"
|
|
#include "vie_encoder.h"
|
|
|
|
// System include
|
|
#include <stdio.h>
|
|
|
|
// Conditional system include
|
|
#if (defined(_WIN32) || defined(_WIN64))
|
|
#include <qos.h>
|
|
#endif
|
|
|
|
namespace webrtc
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetInterface
|
|
// ----------------------------------------------------------------------------
|
|
|
|
ViENetwork* ViENetwork::GetInterface(VideoEngine* videoEngine)
|
|
{
|
|
#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
|
|
if (videoEngine == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
VideoEngineImpl* vieImpl = reinterpret_cast<VideoEngineImpl*> (videoEngine);
|
|
ViENetworkImpl* vieNetworkImpl = vieImpl;
|
|
(*vieNetworkImpl)++; // Increase ref count
|
|
|
|
return vieNetworkImpl;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Release
|
|
//
|
|
// Releases the interface, i.e. reduces the reference counter. The number of
|
|
// remaining references is returned, -1 if released too many times.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int ViENetworkImpl::Release()
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, _instanceId,
|
|
"ViENetwork::Release()");
|
|
(*this)--; // Decrease ref count
|
|
|
|
WebRtc_Word32 refCount = GetCount();
|
|
if (refCount < 0)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, _instanceId,
|
|
"ViENetwork release too many times");
|
|
SetLastError(kViEAPIDoesNotExist);
|
|
return -1;
|
|
}
|
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, _instanceId,
|
|
"ViENetwork reference count: %d", refCount);
|
|
return refCount;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Constructor
|
|
// ----------------------------------------------------------------------------
|
|
|
|
ViENetworkImpl::ViENetworkImpl()
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
|
|
"ViENetworkImpl::ViENetworkImpl() Ctor");
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Destructor
|
|
// ----------------------------------------------------------------------------
|
|
|
|
ViENetworkImpl::~ViENetworkImpl()
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, _instanceId,
|
|
"ViENetworkImpl::~ViENetworkImpl() Dtor");
|
|
}
|
|
|
|
// ============================================================================
|
|
// Receive functions
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetLocalReceiver
|
|
//
|
|
// Initializes the receive socket
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetLocalReceiver(const int videoChannel,
|
|
const unsigned short rtpPort,
|
|
const unsigned short rtcpPort,
|
|
const char* ipAddress)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, rtpPort: %u, rtcpPort: %u, ipAddress: %s)",
|
|
__FUNCTION__, videoChannel, rtpPort, rtcpPort, ipAddress);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
|
|
if (ptrViEChannel->Receiving())
|
|
{
|
|
SetLastError(kViENetworkAlreadyReceiving);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SetLocalReceiver(rtpPort, rtcpPort, ipAddress) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetLocalReceiver
|
|
//
|
|
// Gets settings for an initialized receive socket
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetLocalReceiver(const int videoChannel,
|
|
unsigned short& rtpPort,
|
|
unsigned short& rtcpPort, char* ipAddress)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetLocalReceiver(rtpPort, rtcpPort, ipAddress) != 0)
|
|
{
|
|
SetLastError(kViENetworkLocalReceiverNotSet);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Send functions
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetSendDestination
|
|
//
|
|
// Initializes the send socket
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetSendDestination(const int videoChannel,
|
|
const char* ipAddress,
|
|
const unsigned short rtpPort,
|
|
const unsigned short rtcpPort,
|
|
const unsigned short sourceRtpPort,
|
|
const unsigned short sourceRtcpPort)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, ipAddress: x, rtpPort: %u, rtcpPort: %u, "
|
|
"sourceRtpPort: %u, sourceRtcpPort: %u)",
|
|
__FUNCTION__, rtpPort, rtcpPort, sourceRtpPort,
|
|
sourceRtcpPort);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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 doesn't exist", __FUNCTION__);
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->Sending())
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s Channel already sending.", __FUNCTION__);
|
|
SetLastError(kViENetworkAlreadySending);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SetSendDestination(ipAddress, rtpPort, rtcpPort,
|
|
sourceRtpPort, sourceRtcpPort) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetSendDestination
|
|
//
|
|
// Gets settings for an initialized send socket
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetSendDestination(const int videoChannel, char* ipAddress,
|
|
unsigned short& rtpPort,
|
|
unsigned short& rtcpPort,
|
|
unsigned short& sourceRtpPort,
|
|
unsigned short& sourceRtcpPort)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetSendDestination(ipAddress, rtpPort, rtcpPort,
|
|
sourceRtpPort, sourceRtcpPort) != 0)
|
|
{
|
|
SetLastError(kViENetworkDestinationNotSet);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// External transport
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// RegisterSendTransport
|
|
//
|
|
// Registers the customer implemented send transport
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::RegisterSendTransport(const int videoChannel,
|
|
Transport& transport)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %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;
|
|
}
|
|
|
|
// Get the channel
|
|
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 doesn't exist", __FUNCTION__);
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->Sending())
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s Channel already sending.", __FUNCTION__);
|
|
SetLastError(kViENetworkAlreadySending);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->RegisterSendTransport(transport) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// DeregisterSendTransport
|
|
//
|
|
// Deregisters the send transport implementation from
|
|
// RegisterSendTransport
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::DeregisterSendTransport(const int videoChannel)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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 doesn't exist", __FUNCTION__);
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->Sending())
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s Channel already sending", __FUNCTION__);
|
|
SetLastError(kViENetworkAlreadySending);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->DeregisterSendTransport() != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ReceivedRTPPacket
|
|
//
|
|
// Function for inserting a RTP packet received by a customer transport
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::ReceivedRTPPacket(const int videoChannel, const void* data,
|
|
const int length)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, data: -, length: %d)", __FUNCTION__,
|
|
videoChannel, length);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
return ptrViEChannel->ReceivedRTPPacket(data, length);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ReceivedRTCPPacket
|
|
//
|
|
// Function for inserting a RTCP packet received by a customer transport
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::ReceivedRTCPPacket(const int videoChannel,
|
|
const void* data, const int length)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, data: -, length: %d)", __FUNCTION__,
|
|
videoChannel, length);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
return ptrViEChannel->ReceivedRTCPPacket(data, length);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Get info
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetSourceInfo
|
|
//
|
|
// Retreives informatino about the remote side sockets
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetSourceInfo(const int videoChannel,
|
|
unsigned short& rtpPort,
|
|
unsigned short& rtcpPort, char* ipAddress,
|
|
unsigned int ipAddressLength)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetSourceInfo(rtpPort, rtcpPort, ipAddress,
|
|
ipAddressLength) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetLocalIP
|
|
//
|
|
// Gets the local ip address
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetLocalIP(char ipAddress[64], bool ipv6)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s( ipAddress, ipV6: %d)", __FUNCTION__, ipv6);
|
|
|
|
#ifndef WEBRTC_EXTERNAL_TRANSPORT
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
if (ipAddress == NULL)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: No argument", __FUNCTION__);
|
|
SetLastError(kViENetworkInvalidArgument);
|
|
return -1;
|
|
}
|
|
|
|
WebRtc_UWord8 numSocketThreads = 1;
|
|
UdpTransport* ptrSocketTransport =
|
|
UdpTransport::Create(
|
|
ViEModuleId(_instanceId,-1),numSocketThreads);
|
|
|
|
if (ptrSocketTransport == NULL)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: Could not create socket module", __FUNCTION__);
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
|
|
WebRtc_Word8 localIpAddress[64];
|
|
if (ipv6)
|
|
{
|
|
WebRtc_UWord8 localIP[16];
|
|
if (ptrSocketTransport->LocalHostAddressIPV6(localIP) != 0)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: Could not get local IP", __FUNCTION__);
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
// Convert 128-bit address to character string (a:b:c:d:e:f:g:h)
|
|
sprintf(localIpAddress,
|
|
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x",
|
|
localIP[0], localIP[1], localIP[2], localIP[3], localIP[4],
|
|
localIP[5], localIP[6], localIP[7], localIP[8], localIP[9],
|
|
localIP[10], localIP[11], localIP[12], localIP[13],
|
|
localIP[14], localIP[15]);
|
|
}
|
|
else
|
|
{
|
|
WebRtc_UWord32 localIP = 0;
|
|
if (ptrSocketTransport->LocalHostAddress(localIP) != 0)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: Could not get local IP", __FUNCTION__);
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
// Convert 32-bit address to character string (x.y.z.w)
|
|
sprintf(localIpAddress, "%d.%d.%d.%d", (int) ((localIP >> 24) & 0x0ff),
|
|
(int) ((localIP >> 16) & 0x0ff),
|
|
(int) ((localIP >> 8) & 0x0ff), (int) (localIP & 0x0ff));
|
|
}
|
|
strcpy(ipAddress, localIpAddress);
|
|
UdpTransport::Destroy(
|
|
ptrSocketTransport);
|
|
WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: local ip = %s", __FUNCTION__, localIpAddress);
|
|
|
|
return 0;
|
|
#else
|
|
WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s: not available for external transport", __FUNCTION__);
|
|
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
// ============================================================================
|
|
// IPv6
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// EnableIPv6
|
|
//
|
|
// Enables IPv6
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::EnableIPv6(int videoChannel)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->EnableIPv6() != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// IsIPv6Enabled
|
|
//
|
|
// Returns true if IPv6 is enabled, false otherwise.
|
|
// ----------------------------------------------------------------------------
|
|
bool ViENetworkImpl::IsIPv6Enabled(int videoChannel)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return false;
|
|
}
|
|
return ptrViEChannel->IsIPv6Enabled();
|
|
}
|
|
|
|
// ============================================================================
|
|
// Source IP address and port filter
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetSourceFilter
|
|
//
|
|
// Sets filter source port and IP address. Packets from all other sources
|
|
// will be discarded.
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetSourceFilter(const int videoChannel,
|
|
const unsigned short rtpPort,
|
|
const unsigned short rtcpPort,
|
|
const char* ipAddress)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, rtpPort: %u, rtcpPort: %u, ipAddress: %s)",
|
|
__FUNCTION__, videoChannel, rtpPort, rtcpPort, ipAddress);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SetSourceFilter(rtpPort, rtcpPort, ipAddress) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetSourceFilter
|
|
//
|
|
// Gets vaules set by SetSourceFilter
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetSourceFilter(const int videoChannel,
|
|
unsigned short& rtpPort,
|
|
unsigned short& rtcpPort, char* ipAddress)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetSourceFilter(rtpPort, rtcpPort, ipAddress) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// ToS
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetToS
|
|
//
|
|
// Sets values for ToS
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetSendToS(const int videoChannel, const int DSCP,
|
|
const bool useSetSockOpt = false)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, DSCP: %d, useSetSockOpt: %d)", __FUNCTION__,
|
|
videoChannel, DSCP, useSetSockOpt);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
|
|
#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
|
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(_instanceId, videoChannel),
|
|
" force useSetSockopt=true since there is no alternative"
|
|
" implementation");
|
|
if (ptrViEChannel->SetToS(DSCP, true) != 0)
|
|
#else
|
|
if (ptrViEChannel->SetToS(DSCP, useSetSockOpt) != 0)
|
|
#endif
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetToS
|
|
//
|
|
// Gets values set by SetToS
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetSendToS(const int videoChannel, int& DSCP,
|
|
bool& useSetSockOpt)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetToS((WebRtc_Word32&) DSCP, useSetSockOpt) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// GQoS
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetSendGQoS
|
|
//
|
|
// Sets settings for GQoS. Must be called after SetSendCodec to get correct
|
|
// bitrate setting.
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetSendGQoS(const int videoChannel, const bool enable,
|
|
const int serviceType, const int overrideDSCP)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, enable: %d, serviceType: %d, "
|
|
"overrideDSCP: %d)",
|
|
__FUNCTION__, videoChannel, enable, serviceType, overrideDSCP);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
#if (defined(_WIN32) || defined(_WIN64))
|
|
// Sanity check. We might crash if testing and relying on an OS socket error
|
|
if (enable
|
|
&& (serviceType != SERVICETYPE_BESTEFFORT)
|
|
&& (serviceType != SERVICETYPE_CONTROLLEDLOAD)
|
|
&& (serviceType != SERVICETYPE_GUARANTEED) &&
|
|
(serviceType != SERVICETYPE_QUALITATIVE))
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s: service type %d not supported", __FUNCTION__,
|
|
videoChannel, serviceType);
|
|
SetLastError(kViENetworkServiceTypeNotSupported);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
ViEEncoder* ptrVieEncoder = cs.Encoder(videoChannel);
|
|
if (ptrVieEncoder == NULL)
|
|
{
|
|
// The channel doesn't exists
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
VideoCodec videoCodec;
|
|
if (ptrVieEncoder->GetEncoder(videoCodec) != 0)
|
|
{
|
|
// Could not get
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s: Could not get max bitrate for the channel",
|
|
__FUNCTION__);
|
|
SetLastError(kViENetworkSendCodecNotSet);
|
|
return -1;
|
|
}
|
|
if(ptrViEChannel->SetSendGQoS(enable, serviceType, videoCodec.maxBitrate,
|
|
overrideDSCP)!=0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
|
|
#else
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s: Not supported",
|
|
__FUNCTION__);
|
|
SetLastError(kViENetworkNotSupported);
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// GetSendGQoS
|
|
//
|
|
// Gets the settigns set by SetSendGQoS
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::GetSendGQoS(const int videoChannel, bool& enabled,
|
|
int& serviceType, int& overrideDSCP)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->GetSendGQoS(enabled, (WebRtc_Word32&) serviceType,
|
|
(WebRtc_Word32&) overrideDSCP) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
|
|
// ============================================================================
|
|
// Network settings
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetMTU
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetMTU(int videoChannel, unsigned int mtu)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d, mtu: %u)",
|
|
__FUNCTION__, videoChannel, mtu);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SetMTU(mtu) != 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
|
|
}
|
|
|
|
// ============================================================================
|
|
// Packet timout notification
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetPacketTimeoutNotification
|
|
//
|
|
// Sets the time for packet timout notifications
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetPacketTimeoutNotification(const int videoChannel,
|
|
bool enable,
|
|
int timeoutSeconds)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, enable: %d, timeoutSeconds: %u)",
|
|
__FUNCTION__, videoChannel, enable, timeoutSeconds);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SetPacketTimeoutNotification(enable, timeoutSeconds)
|
|
!= 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Periodic dead-or-alive reports
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// RegisterObserver
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::RegisterObserver(const int videoChannel,
|
|
ViENetworkObserver& observer)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->RegisterNetworkObserver(&observer) != 0)
|
|
{
|
|
SetLastError(kViENetworkObserverAlreadyRegistered);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// DeregisterObserver
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::DeregisterObserver(const int videoChannel)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel), "%s(channel: %d)",
|
|
__FUNCTION__, videoChannel);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (!ptrViEChannel->NetworkObserverRegistered())
|
|
{
|
|
SetLastError(kViENetworkObserverNotRegistered);
|
|
return -1;
|
|
}
|
|
return ptrViEChannel->RegisterNetworkObserver(NULL);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SetPeriodicDeadOrAliveStatus
|
|
//
|
|
// Enables/disables the dead-or-alive callback
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SetPeriodicDeadOrAliveStatus(const int videoChannel,
|
|
bool enable,
|
|
unsigned int sampleTimeSeconds)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, enable: %d, sampleTimeSeconds: %ul)",
|
|
__FUNCTION__, videoChannel, enable, sampleTimeSeconds);
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (!ptrViEChannel->NetworkObserverRegistered())
|
|
{
|
|
SetLastError(kViENetworkObserverNotRegistered);
|
|
return -1;
|
|
}
|
|
|
|
if (ptrViEChannel->SetPeriodicDeadOrAliveStatus(enable, sampleTimeSeconds)
|
|
!= 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Send packet using the User Datagram Protocol (UDP)
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// SendUDPPacket
|
|
//
|
|
// Send an extra UDP packet
|
|
// ----------------------------------------------------------------------------
|
|
int ViENetworkImpl::SendUDPPacket(const int videoChannel, const void* data,
|
|
const unsigned int length,
|
|
int& transmittedBytes,
|
|
bool useRtcpSocket = false)
|
|
{
|
|
WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
|
|
ViEId(_instanceId, videoChannel),
|
|
"%s(channel: %d, data: -, length: %d, transmitterBytes: -, "
|
|
"useRtcpSocket: %d)", __FUNCTION__, videoChannel, length,
|
|
useRtcpSocket);
|
|
if (!IsInitialized())
|
|
{
|
|
SetLastError(kViENotInitialized);
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_instanceId),
|
|
"%s - ViE instance %d not initialized", __FUNCTION__,
|
|
_instanceId);
|
|
return -1;
|
|
}
|
|
|
|
// Get the channel
|
|
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), "Channel doesn't exist");
|
|
SetLastError(kViENetworkInvalidChannelId);
|
|
return -1;
|
|
}
|
|
if (ptrViEChannel->SendUDPPacket((const WebRtc_Word8*) data, length,
|
|
(WebRtc_Word32&) transmittedBytes,
|
|
useRtcpSocket) < 0)
|
|
{
|
|
SetLastError(kViENetworkUnknownError);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
} // namespace webrtc
|