/* * 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 "webrtc/system_wrappers/include/critical_section_wrapper.h" #include "webrtc/system_wrappers/include/file_wrapper.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/voice_engine/include/voe_errors.h" #include "webrtc/voice_engine/voe_rtp_rtcp_impl.h" #include "webrtc/voice_engine/voice_engine_impl.h" #include "webrtc/voice_engine/channel.h" #include "webrtc/voice_engine/transmit_mixer.h" namespace webrtc { VoERTP_RTCP* VoERTP_RTCP::GetInterface(VoiceEngine* voiceEngine) { #ifndef WEBRTC_VOICE_ENGINE_RTP_RTCP_API return NULL; #else if (NULL == voiceEngine) { return NULL; } VoiceEngineImpl* s = static_cast(voiceEngine); s->AddRef(); return s; #endif } #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API VoERTP_RTCPImpl::VoERTP_RTCPImpl(voe::SharedData* shared) : _shared(shared) { WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), "VoERTP_RTCPImpl::VoERTP_RTCPImpl() - ctor"); } VoERTP_RTCPImpl::~VoERTP_RTCPImpl() { WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), "VoERTP_RTCPImpl::~VoERTP_RTCPImpl() - dtor"); } int VoERTP_RTCPImpl::SetLocalSSRC(int channel, unsigned int ssrc) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetLocalSSRC(channel=%d, %lu)", channel, ssrc); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "SetLocalSSRC() failed to locate channel"); return -1; } return channelPtr->SetLocalSSRC(ssrc); } int VoERTP_RTCPImpl::GetLocalSSRC(int channel, unsigned int& ssrc) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetLocalSSRC() failed to locate channel"); return -1; } return channelPtr->GetLocalSSRC(ssrc); } int VoERTP_RTCPImpl::GetRemoteSSRC(int channel, unsigned int& ssrc) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRemoteSSRC() failed to locate channel"); return -1; } return channelPtr->GetRemoteSSRC(ssrc); } int VoERTP_RTCPImpl::SetSendAudioLevelIndicationStatus(int channel, bool enable, unsigned char id) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetSendAudioLevelIndicationStatus(channel=%d, enable=%d," " ID=%u)", channel, enable, id); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } if (enable && (id < kVoiceEngineMinRtpExtensionId || id > kVoiceEngineMaxRtpExtensionId)) { // [RFC5285] The 4-bit id is the local identifier of this element in // the range 1-14 inclusive. _shared->SetLastError( VE_INVALID_ARGUMENT, kTraceError, "SetSendAudioLevelIndicationStatus() invalid ID parameter"); return -1; } // Set state and id for the specified channel. voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError( VE_CHANNEL_NOT_VALID, kTraceError, "SetSendAudioLevelIndicationStatus() failed to locate channel"); return -1; } return channelPtr->SetSendAudioLevelIndicationStatus(enable, id); } int VoERTP_RTCPImpl::SetReceiveAudioLevelIndicationStatus(int channel, bool enable, unsigned char id) { WEBRTC_TRACE( kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetReceiveAudioLevelIndicationStatus(channel=%d, enable=%d, id=%u)", channel, enable, id); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } if (enable && (id < kVoiceEngineMinRtpExtensionId || id > kVoiceEngineMaxRtpExtensionId)) { // [RFC5285] The 4-bit id is the local identifier of this element in // the range 1-14 inclusive. _shared->SetLastError( VE_INVALID_ARGUMENT, kTraceError, "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter"); return -1; } // Set state and id for the specified channel. voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channel_ptr = ch.channel(); if (channel_ptr == NULL) { _shared->SetLastError( VE_CHANNEL_NOT_VALID, kTraceError, "SetReceiveAudioLevelIndicationStatus() failed to locate channel"); return -1; } return channel_ptr->SetReceiveAudioLevelIndicationStatus(enable, id); } int VoERTP_RTCPImpl::SetSendAbsoluteSenderTimeStatus(int channel, bool enable, unsigned char id) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetSendAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)", channel, enable, id); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } if (enable && (id < kVoiceEngineMinRtpExtensionId || id > kVoiceEngineMaxRtpExtensionId)) { // [RFC5285] The 4-bit id is the local identifier of this element in // the range 1-14 inclusive. _shared->SetLastError( VE_INVALID_ARGUMENT, kTraceError, "SetSendAbsoluteSenderTimeStatus() invalid id parameter"); return -1; } // Set state and id for the specified channel. voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError( VE_CHANNEL_NOT_VALID, kTraceError, "SetSendAbsoluteSenderTimeStatus() failed to locate channel"); return -1; } return channelPtr->SetSendAbsoluteSenderTimeStatus(enable, id); } int VoERTP_RTCPImpl::SetReceiveAbsoluteSenderTimeStatus(int channel, bool enable, unsigned char id) { WEBRTC_TRACE( kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetReceiveAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)", channel, enable, id); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } if (enable && (id < kVoiceEngineMinRtpExtensionId || id > kVoiceEngineMaxRtpExtensionId)) { // [RFC5285] The 4-bit id is the local identifier of this element in // the range 1-14 inclusive. _shared->SetLastError( VE_INVALID_ARGUMENT, kTraceError, "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter"); return -1; } // Set state and id for the specified channel. voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError( VE_CHANNEL_NOT_VALID, kTraceError, "SetReceiveAbsoluteSenderTimeStatus() failed to locate channel"); return -1; } return channelPtr->SetReceiveAbsoluteSenderTimeStatus(enable, id); } int VoERTP_RTCPImpl::SetRTCPStatus(int channel, bool enable) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetRTCPStatus(channel=%d, enable=%d)", channel, enable); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "SetRTCPStatus() failed to locate channel"); return -1; } channelPtr->SetRTCPStatus(enable); return 0; } int VoERTP_RTCPImpl::GetRTCPStatus(int channel, bool& enabled) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRTCPStatus() failed to locate channel"); return -1; } return channelPtr->GetRTCPStatus(enabled); } int VoERTP_RTCPImpl::SetRTCP_CNAME(int channel, const char cName[256]) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetRTCP_CNAME(channel=%d, cName=%s)", channel, cName); if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "SetRTCP_CNAME() failed to locate channel"); return -1; } return channelPtr->SetRTCP_CNAME(cName); } int VoERTP_RTCPImpl::GetRemoteRTCP_CNAME(int channel, char cName[256]) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRemoteRTCP_CNAME() failed to locate channel"); return -1; } return channelPtr->GetRemoteRTCP_CNAME(cName); } int VoERTP_RTCPImpl::GetRemoteRTCPData( int channel, unsigned int& NTPHigh, // from sender info in SR unsigned int& NTPLow, // from sender info in SR unsigned int& timestamp, // from sender info in SR unsigned int& playoutTimestamp, // derived locally unsigned int* jitter, // from report block 1 in SR/RR unsigned short* fractionLost) // from report block 1 in SR/RR { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRemoteRTCP_CNAME() failed to locate channel"); return -1; } return channelPtr->GetRemoteRTCPData(NTPHigh, NTPLow, timestamp, playoutTimestamp, jitter, fractionLost); } int VoERTP_RTCPImpl::GetRTPStatistics(int channel, unsigned int& averageJitterMs, unsigned int& maxJitterMs, unsigned int& discardedPackets) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRTPStatistics() failed to locate channel"); return -1; } return channelPtr->GetRTPStatistics(averageJitterMs, maxJitterMs, discardedPackets); } int VoERTP_RTCPImpl::GetRTCPStatistics(int channel, CallStatistics& stats) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetRTPStatistics() failed to locate channel"); return -1; } return channelPtr->GetRTPStatistics(stats); } int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks( int channel, std::vector* report_blocks) { if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channel_ptr = ch.channel(); if (channel_ptr == NULL) { _shared->SetLastError( VE_CHANNEL_NOT_VALID, kTraceError, "GetRemoteRTCPReportBlocks() failed to locate channel"); return -1; } return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks); } int VoERTP_RTCPImpl::SetREDStatus(int channel, bool enable, int redPayloadtype) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetREDStatus(channel=%d, enable=%d, redPayloadtype=%d)", channel, enable, redPayloadtype); #ifdef WEBRTC_CODEC_RED if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "SetREDStatus() failed to locate channel"); return -1; } return channelPtr->SetREDStatus(enable, redPayloadtype); #else _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, "SetREDStatus() RED is not supported"); return -1; #endif } int VoERTP_RTCPImpl::GetREDStatus(int channel, bool& enabled, int& redPayloadtype) { #ifdef WEBRTC_CODEC_RED if (!_shared->statistics().Initialized()) { _shared->SetLastError(VE_NOT_INITED, kTraceError); return -1; } voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "GetREDStatus() failed to locate channel"); return -1; } return channelPtr->GetREDStatus(enabled, redPayloadtype); #else _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, "GetREDStatus() RED is not supported"); return -1; #endif } int VoERTP_RTCPImpl::SetNACKStatus(int channel, bool enable, int maxNoPackets) { WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), "SetNACKStatus(channel=%d, enable=%d, maxNoPackets=%d)", channel, enable, maxNoPackets); voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); voe::Channel* channelPtr = ch.channel(); if (channelPtr == NULL) { _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, "SetNACKStatus() failed to locate channel"); return -1; } channelPtr->SetNACKStatus(enable, maxNoPackets); return 0; } #endif // #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API } // namespace webrtc