blob: b4bb0e9a6c12b2f51e51d834ee20389df71b7850 [file] [log] [blame]
/*
* Copyright (c) 2012 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.
*/
#include "video_engine/vie_network_impl.h"
#include <stdio.h>
#if (defined(WIN32_) || defined(WIN64_))
#include <qos.h>
#endif
#include "engine_configurations.h"
#include "system_wrappers/interface/trace.h"
#include "video_engine/include/vie_errors.h"
#include "video_engine/vie_channel.h"
#include "video_engine/vie_channel_manager.h"
#include "video_engine/vie_defines.h"
#include "video_engine/vie_encoder.h"
#include "video_engine/vie_impl.h"
#include "video_engine/vie_shared_data.h"
namespace webrtc {
ViENetwork* ViENetwork::GetInterface(VideoEngine* video_engine) {
#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
if (!video_engine) {
return NULL;
}
VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
ViENetworkImpl* vie_networkImpl = vie_impl;
// Increase ref count.
(*vie_networkImpl)++;
return vie_networkImpl;
#else
return NULL;
#endif
}
int ViENetworkImpl::Release() {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
"ViENetwork::Release()");
// Decrease ref count.
(*this)--;
WebRtc_Word32 ref_count = GetCount();
if (ref_count < 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
"ViENetwork release too many times");
shared_data_->SetLastError(kViEAPIDoesNotExist);
return -1;
}
WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
"ViENetwork reference count: %d", ref_count);
return ref_count;
}
ViENetworkImpl::ViENetworkImpl(ViESharedData* shared_data)
: shared_data_(shared_data) {
WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
"ViENetworkImpl::ViENetworkImpl() Ctor");
}
ViENetworkImpl::~ViENetworkImpl() {
WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
"ViENetworkImpl::~ViENetworkImpl() Dtor");
}
int ViENetworkImpl::SetLocalReceiver(const int video_channel,
const unsigned short rtp_port,
const unsigned short rtcp_port,
const char* ip_address) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, rtp_port: %u, rtcp_port: %u, ip_address: %s)",
__FUNCTION__, video_channel, rtp_port, rtcp_port, ip_address);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
// The channel doesn't exists.
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->Receiving()) {
shared_data_->SetLastError(kViENetworkAlreadyReceiving);
return -1;
}
if (vie_channel->SetLocalReceiver(rtp_port, rtcp_port, ip_address) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::GetLocalReceiver(const int video_channel,
unsigned short& rtp_port,
unsigned short& rtcp_port,
char* ip_address) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetLocalReceiver(rtp_port, rtcp_port, ip_address) != 0) {
shared_data_->SetLastError(kViENetworkLocalReceiverNotSet);
return -1;
}
return 0;
}
int ViENetworkImpl::SetSendDestination(const int video_channel,
const char* ip_address,
const unsigned short rtp_port,
const unsigned short rtcp_port,
const unsigned short source_rtp_port,
const unsigned short source_rtcp_port) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, ip_address: %s, rtp_port: %u, rtcp_port: %u, "
"sourceRtpPort: %u, source_rtcp_port: %u)",
__FUNCTION__, video_channel, ip_address, rtp_port, rtcp_port,
source_rtp_port, source_rtcp_port);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel doesn't exist", __FUNCTION__);
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->Sending()) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel already sending.", __FUNCTION__);
shared_data_->SetLastError(kViENetworkAlreadySending);
return -1;
}
if (vie_channel->SetSendDestination(ip_address, rtp_port, rtcp_port,
source_rtp_port,
source_rtcp_port) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::GetSendDestination(const int video_channel,
char* ip_address,
unsigned short& rtp_port,
unsigned short& rtcp_port,
unsigned short& source_rtp_port,
unsigned short& source_rtcp_port) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetSendDestination(ip_address, rtp_port, rtcp_port,
source_rtp_port,
source_rtcp_port) != 0) {
shared_data_->SetLastError(kViENetworkDestinationNotSet);
return -1;
}
return 0;
}
int ViENetworkImpl::RegisterSendTransport(const int video_channel,
Transport& transport) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel doesn't exist", __FUNCTION__);
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->Sending()) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel already sending.", __FUNCTION__);
shared_data_->SetLastError(kViENetworkAlreadySending);
return -1;
}
if (vie_channel->RegisterSendTransport(transport) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::DeregisterSendTransport(const int video_channel) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel doesn't exist", __FUNCTION__);
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->Sending()) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s Channel already sending", __FUNCTION__);
shared_data_->SetLastError(kViENetworkAlreadySending);
return -1;
}
if (vie_channel->DeregisterSendTransport() != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::ReceivedRTPPacket(const int video_channel, const void* data,
const int length) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, data: -, length: %d)", __FUNCTION__,
video_channel, length);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
// The channel doesn't exists
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
return vie_channel->ReceivedRTPPacket(data, length);
}
int ViENetworkImpl::ReceivedRTCPPacket(const int video_channel,
const void* data, const int length) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, data: -, length: %d)", __FUNCTION__,
video_channel, length);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
return vie_channel->ReceivedRTCPPacket(data, length);
}
int ViENetworkImpl::GetSourceInfo(const int video_channel,
unsigned short& rtp_port,
unsigned short& rtcp_port, char* ip_address,
unsigned int ip_address_length) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetSourceInfo(rtp_port, rtcp_port, ip_address,
ip_address_length) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::GetLocalIP(char ip_address[64], bool ipv6) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s( ip_address, ipV6: %d)", __FUNCTION__, ipv6);
#ifndef WEBRTC_EXTERNAL_TRANSPORT
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
if (!ip_address) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: No argument", __FUNCTION__);
shared_data_->SetLastError(kViENetworkInvalidArgument);
return -1;
}
WebRtc_UWord8 num_socket_threads = 1;
UdpTransport* socket_transport = UdpTransport::Create(
ViEModuleId(shared_data_->instance_id(), -1), num_socket_threads);
if (!socket_transport) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: Could not create socket module", __FUNCTION__);
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
char local_ip_address[64];
if (ipv6) {
char local_ip[16];
if (socket_transport->LocalHostAddressIPV6(local_ip) != 0) {
UdpTransport::Destroy(socket_transport);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: Could not get local IP", __FUNCTION__);
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
// Convert 128-bit address to character string (a:b:c:d:e:f:g:h).
sprintf(local_ip_address,
"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:"
"%.2x%.2x",
local_ip[0], local_ip[1], local_ip[2], local_ip[3], local_ip[4],
local_ip[5], local_ip[6], local_ip[7], local_ip[8], local_ip[9],
local_ip[10], local_ip[11], local_ip[12], local_ip[13],
local_ip[14], local_ip[15]);
} else {
WebRtc_UWord32 local_ip = 0;
if (socket_transport->LocalHostAddress(local_ip) != 0) {
UdpTransport::Destroy(socket_transport);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: Could not get local IP", __FUNCTION__);
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
// Convert 32-bit address to character string (x.y.z.w).
sprintf(local_ip_address, "%d.%d.%d.%d",
static_cast<int>((local_ip >> 24) & 0x0ff),
static_cast<int>((local_ip >> 16) & 0x0ff),
static_cast<int>((local_ip >> 8) & 0x0ff),
static_cast<int>(local_ip & 0x0ff));
}
strcpy(ip_address, local_ip_address);
UdpTransport::Destroy(socket_transport);
WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: local ip = %s", __FUNCTION__, local_ip_address);
return 0;
#else
WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s: not available for external transport", __FUNCTION__);
return -1;
#endif
}
int ViENetworkImpl::EnableIPv6(int video_channel) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->EnableIPv6() != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
bool ViENetworkImpl::IsIPv6Enabled(int video_channel) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return false;
}
return vie_channel->IsIPv6Enabled();
}
int ViENetworkImpl::SetSourceFilter(const int video_channel,
const unsigned short rtp_port,
const unsigned short rtcp_port,
const char* ip_address) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, rtp_port: %u, rtcp_port: %u, ip_address: %s)",
__FUNCTION__, video_channel, rtp_port, rtcp_port, ip_address);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->SetSourceFilter(rtp_port, rtcp_port, ip_address) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::GetSourceFilter(const int video_channel,
unsigned short& rtp_port,
unsigned short& rtcp_port,
char* ip_address) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetSourceFilter(rtp_port, rtcp_port, ip_address) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::SetSendToS(const int video_channel, const int DSCP,
const bool use_set_sockOpt = false) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, DSCP: %d, use_set_sockOpt: %d)", __FUNCTION__,
video_channel, DSCP, use_set_sockOpt);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
WEBRTC_TRACE(kTraceInfo, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
" force use_set_sockopt=true since there is no alternative"
" implementation");
if (vie_channel->SetToS(DSCP, true) != 0) {
#else
if (vie_channel->SetToS(DSCP, use_set_sockOpt) != 0) {
#endif
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::GetSendToS(const int video_channel, int& DSCP,
bool& use_set_sockOpt) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetToS((WebRtc_Word32&) DSCP, use_set_sockOpt) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::SetSendGQoS(const int video_channel, const bool enable,
const int service_type,
const int overrideDSCP) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, enable: %d, service_type: %d, "
"overrideDSCP: %d)", __FUNCTION__, video_channel, enable,
service_type, overrideDSCP);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
#if (defined(WIN32_) || defined(WIN64_))
// Sanity check. We might crash if testing and relying on an OS socket error.
if (enable &&
(service_type != SERVICETYPE_BESTEFFORT) &&
(service_type != SERVICETYPE_CONTROLLEDLOAD) &&
(service_type != SERVICETYPE_GUARANTEED) &&
(service_type != SERVICETYPE_QUALITATIVE)) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: service type %d not supported", __FUNCTION__,
video_channel, service_type);
shared_data_->SetLastError(kViENetworkServiceTypeNotSupported);
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
ViEEncoder* vie_encoder = cs.Encoder(video_channel);
if (!vie_encoder) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
VideoCodec video_codec;
if (vie_encoder->GetEncoder(video_codec) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Could not get max bitrate for the channel",
__FUNCTION__);
shared_data_->SetLastError(kViENetworkSendCodecNotSet);
return -1;
}
if (vie_channel->SetSendGQoS(enable, service_type, video_codec.maxBitrate,
overrideDSCP) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
#else
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Not supported", __FUNCTION__);
shared_data_->SetLastError(kViENetworkNotSupported);
return -1;
#endif
}
int ViENetworkImpl::GetSendGQoS(const int video_channel, bool& enabled,
int& service_type, int& overrideDSCP) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->GetSendGQoS(enabled, service_type, overrideDSCP) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::SetMTU(int video_channel, unsigned int mtu) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, mtu: %u)", __FUNCTION__, video_channel, mtu);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->SetMTU(mtu) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::SetPacketTimeoutNotification(const int video_channel,
bool enable,
int timeout_seconds) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, enable: %d, timeout_seconds: %u)",
__FUNCTION__, video_channel, enable, timeout_seconds);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->SetPacketTimeoutNotification(enable,
timeout_seconds) != 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::RegisterObserver(const int video_channel,
ViENetworkObserver& observer) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->RegisterNetworkObserver(&observer) != 0) {
shared_data_->SetLastError(kViENetworkObserverAlreadyRegistered);
return -1;
}
return 0;
}
int ViENetworkImpl::DeregisterObserver(const int video_channel) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (!vie_channel->NetworkObserverRegistered()) {
shared_data_->SetLastError(kViENetworkObserverNotRegistered);
return -1;
}
return vie_channel->RegisterNetworkObserver(NULL);
}
int ViENetworkImpl::SetPeriodicDeadOrAliveStatus(
const int video_channel,
bool enable,
unsigned int sample_time_seconds) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, enable: %d, sample_time_seconds: %ul)",
__FUNCTION__, video_channel, enable, sample_time_seconds);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (!vie_channel->NetworkObserverRegistered()) {
shared_data_->SetLastError(kViENetworkObserverNotRegistered);
return -1;
}
if (vie_channel->SetPeriodicDeadOrAliveStatus(enable, sample_time_seconds)
!= 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
int ViENetworkImpl::SendUDPPacket(const int video_channel, const void* data,
const unsigned int length,
int& transmitted_bytes,
bool use_rtcp_socket = false) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, data: -, length: %d, transmitter_bytes: -, "
"useRtcpSocket: %d)", __FUNCTION__, video_channel, length,
use_rtcp_socket);
if (!shared_data_->Initialized()) {
shared_data_->SetLastError(kViENotInitialized);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
"%s - ViE instance %d not initialized", __FUNCTION__,
shared_data_->instance_id());
return -1;
}
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"Channel doesn't exist");
shared_data_->SetLastError(kViENetworkInvalidChannelId);
return -1;
}
if (vie_channel->SendUDPPacket((const WebRtc_Word8*) data, length,
(WebRtc_Word32&) transmitted_bytes,
use_rtcp_socket) < 0) {
shared_data_->SetLastError(kViENetworkUnknownError);
return -1;
}
return 0;
}
} // namespace webrtc