/* * 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 // Conditional system include #if (defined(_WIN32) || defined(_WIN64)) #include #endif namespace webrtc { // ---------------------------------------------------------------------------- // GetInterface // ---------------------------------------------------------------------------- ViENetwork* ViENetwork::GetInterface(VideoEngine* videoEngine) { #ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API if (videoEngine == NULL) { return NULL; } VideoEngineImpl* vieImpl = reinterpret_cast (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