| /* |
| * 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/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<VoiceEngineImpl*>(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<ReportBlock>* 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::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 |