400 lines
15 KiB
C++
400 lines
15 KiB
C++
|
/*
|
||
|
* 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::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);
|
||
|
_shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
|
||
|
"SetREDStatus() RED is not supported");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int VoERTP_RTCPImpl::GetREDStatus(int channel,
|
||
|
bool& enabled,
|
||
|
int& redPayloadtype) {
|
||
|
_shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
|
||
|
"GetREDStatus() RED is not supported");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
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
|