| /* |
| * 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. |
| */ |
| |
| #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" |
| |
| 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, instance_id_, |
| "ViENetwork::Release()"); |
| // Decrease ref count. |
| (*this)--; |
| |
| WebRtc_Word32 ref_count = GetCount(); |
| if (ref_count < 0) { |
| WEBRTC_TRACE(kTraceWarning, kTraceVideo, instance_id_, |
| "ViENetwork release too many times"); |
| SetLastError(kViEAPIDoesNotExist); |
| return -1; |
| } |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, instance_id_, |
| "ViENetwork reference count: %d", ref_count); |
| return ref_count; |
| } |
| |
| ViENetworkImpl::ViENetworkImpl() { |
| WEBRTC_TRACE(kTraceMemory, kTraceVideo, instance_id_, |
| "ViENetworkImpl::ViENetworkImpl() Ctor"); |
| } |
| |
| ViENetworkImpl::~ViENetworkImpl() { |
| WEBRTC_TRACE(kTraceMemory, kTraceVideo, 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(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 (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| // The channel doesn't exists. |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| |
| if (vie_channel->Receiving()) { |
| SetLastError(kViENetworkAlreadyReceiving); |
| return -1; |
| } |
| if (vie_channel->SetLocalReceiver(rtp_port, rtcp_port, ip_address) != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetLocalReceiver(rtp_port, rtcp_port, ip_address) != 0) { |
| 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(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 (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel doesn't exist", __FUNCTION__); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->Sending()) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel already sending.", __FUNCTION__); |
| SetLastError(kViENetworkAlreadySending); |
| return -1; |
| } |
| if (vie_channel->SetSendDestination(ip_address, rtp_port, rtcp_port, |
| source_rtp_port, |
| source_rtcp_port) != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, |
| ViEId(instance_id_, video_channel), "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetSendDestination(ip_address, rtp_port, rtcp_port, |
| source_rtp_port, |
| source_rtcp_port) != 0) { |
| SetLastError(kViENetworkDestinationNotSet); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::RegisterSendTransport(const int video_channel, |
| Transport& transport) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel doesn't exist", __FUNCTION__); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->Sending()) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel already sending.", __FUNCTION__); |
| SetLastError(kViENetworkAlreadySending); |
| return -1; |
| } |
| if (vie_channel->RegisterSendTransport(transport) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::DeregisterSendTransport(const int video_channel) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel doesn't exist", __FUNCTION__); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->Sending()) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s Channel already sending", __FUNCTION__); |
| SetLastError(kViENetworkAlreadySending); |
| return -1; |
| } |
| if (vie_channel->DeregisterSendTransport() != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::ReceivedRTPPacket(const int video_channel, const void* data, |
| const int length) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d, data: -, length: %d)", __FUNCTION__, |
| video_channel, length); |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| // The channel doesn't exists |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| 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(instance_id_, video_channel), |
| "%s(channel: %d, data: -, length: %d)", __FUNCTION__, |
| video_channel, length); |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| 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(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetSourceInfo(rtp_port, rtcp_port, ip_address, |
| ip_address_length) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::GetLocalIP(char ip_address[64], bool ipv6) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_), |
| "%s( ip_address, ipV6: %d)", __FUNCTION__, ipv6); |
| |
| #ifndef WEBRTC_EXTERNAL_TRANSPORT |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| |
| if (!ip_address) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s: No argument", __FUNCTION__); |
| SetLastError(kViENetworkInvalidArgument); |
| return -1; |
| } |
| |
| WebRtc_UWord8 num_socket_threads = 1; |
| UdpTransport* socket_transport = UdpTransport::Create( |
| ViEModuleId(instance_id_, -1), num_socket_threads); |
| |
| if (!socket_transport) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s: Could not create socket module", __FUNCTION__); |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| |
| WebRtc_Word8 local_ip_address[64]; |
| if (ipv6) { |
| WebRtc_UWord8 local_ip[16]; |
| if (socket_transport->LocalHostAddressIPV6(local_ip) != 0) { |
| UdpTransport::Destroy(socket_transport); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%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(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(instance_id_), |
| "%s: Could not get local IP", __FUNCTION__); |
| 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(instance_id_), |
| "%s: local ip = %s", __FUNCTION__, local_ip_address); |
| return 0; |
| #else |
| WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(instance_id_), |
| "%s: not available for external transport", __FUNCTION__); |
| |
| return -1; |
| #endif |
| } |
| |
| int ViENetworkImpl::EnableIPv6(int video_channel) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->EnableIPv6() != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| bool ViENetworkImpl::IsIPv6Enabled(int video_channel) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| 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(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(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->SetSourceFilter(rtp_port, rtcp_port, ip_address) != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetSourceFilter(rtp_port, rtcp_port, ip_address) != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d, DSCP: %d, use_set_sockOpt: %d)", __FUNCTION__, |
| video_channel, DSCP, use_set_sockOpt); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| |
| #if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) |
| WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(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 |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::GetSendToS(const int video_channel, int& DSCP, |
| bool& use_set_sockOpt) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetToS((WebRtc_Word32&) DSCP, use_set_sockOpt) != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d, enable: %d, service_type: %d, " |
| "overrideDSCP: %d)", __FUNCTION__, video_channel, enable, |
| service_type, overrideDSCP); |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| 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(instance_id_, video_channel), |
| "%s: service type %d not supported", __FUNCTION__, |
| video_channel, service_type); |
| SetLastError(kViENetworkServiceTypeNotSupported); |
| return -1; |
| } |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| ViEEncoder* vie_encoder = cs.Encoder(video_channel); |
| if (!vie_encoder) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| VideoCodec video_codec; |
| if (vie_encoder->GetEncoder(video_codec) != 0) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s: Could not get max bitrate for the channel", |
| __FUNCTION__); |
| SetLastError(kViENetworkSendCodecNotSet); |
| return -1; |
| } |
| if (vie_channel->SetSendGQoS(enable, service_type, video_codec.maxBitrate, |
| overrideDSCP) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| #else |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s: Not supported", __FUNCTION__); |
| SetLastError(kViENetworkNotSupported); |
| return -1; |
| #endif |
| } |
| |
| int ViENetworkImpl::GetSendGQoS(const int video_channel, bool& enabled, |
| int& service_type, int& overrideDSCP) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->GetSendGQoS(enabled, service_type, overrideDSCP) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::SetMTU(int video_channel, unsigned int mtu) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d, mtu: %u)", __FUNCTION__, video_channel, mtu); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->SetMTU(mtu) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::SetPacketTimeoutNotification(const int video_channel, |
| bool enable, |
| int timeout_seconds) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d, enable: %d, timeout_seconds: %u)", |
| __FUNCTION__, video_channel, enable, timeout_seconds); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->SetPacketTimeoutNotification(enable, |
| timeout_seconds) != 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::RegisterObserver(const int video_channel, |
| ViENetworkObserver& observer) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->RegisterNetworkObserver(&observer) != 0) { |
| SetLastError(kViENetworkObserverAlreadyRegistered); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int ViENetworkImpl::DeregisterObserver(const int video_channel) { |
| WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel), |
| "%s(channel: %d)", __FUNCTION__, video_channel); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (!vie_channel->NetworkObserverRegistered()) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d, enable: %d, sample_time_seconds: %ul)", |
| __FUNCTION__, video_channel, enable, sample_time_seconds); |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (!vie_channel->NetworkObserverRegistered()) { |
| SetLastError(kViENetworkObserverNotRegistered); |
| return -1; |
| } |
| if (vie_channel->SetPeriodicDeadOrAliveStatus(enable, sample_time_seconds) |
| != 0) { |
| 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(instance_id_, video_channel), |
| "%s(channel: %d, data: -, length: %d, transmitter_bytes: -, " |
| "useRtcpSocket: %d)", __FUNCTION__, video_channel, length, |
| use_rtcp_socket); |
| if (!Initialized()) { |
| SetLastError(kViENotInitialized); |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_), |
| "%s - ViE instance %d not initialized", __FUNCTION__, |
| instance_id_); |
| return -1; |
| } |
| ViEChannelManagerScoped cs(channel_manager_); |
| ViEChannel* vie_channel = cs.Channel(video_channel); |
| if (!vie_channel) { |
| WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel), |
| "Channel doesn't exist"); |
| SetLastError(kViENetworkInvalidChannelId); |
| return -1; |
| } |
| if (vie_channel->SendUDPPacket((const WebRtc_Word8*) data, length, |
| (WebRtc_Word32&) transmitted_bytes, |
| use_rtcp_socket) < 0) { |
| SetLastError(kViENetworkUnknownError); |
| return -1; |
| } |
| return 0; |
| } |
| |
| } // namespace webrtc |