1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 12#include "webrtc/system_wrappers/include/file_wrapper.h" 13#include "webrtc/system_wrappers/include/trace.h" 14#include "webrtc/voice_engine/include/voe_errors.h" 15#include "webrtc/voice_engine/voe_rtp_rtcp_impl.h" 16#include "webrtc/voice_engine/voice_engine_impl.h" 17 18#include "webrtc/voice_engine/channel.h" 19#include "webrtc/voice_engine/transmit_mixer.h" 20 21namespace webrtc { 22 23VoERTP_RTCP* VoERTP_RTCP::GetInterface(VoiceEngine* voiceEngine) { 24#ifndef WEBRTC_VOICE_ENGINE_RTP_RTCP_API 25 return NULL; 26#else 27 if (NULL == voiceEngine) { 28 return NULL; 29 } 30 VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); 31 s->AddRef(); 32 return s; 33#endif 34} 35 36#ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API 37 38VoERTP_RTCPImpl::VoERTP_RTCPImpl(voe::SharedData* shared) : _shared(shared) { 39 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 40 "VoERTP_RTCPImpl::VoERTP_RTCPImpl() - ctor"); 41} 42 43VoERTP_RTCPImpl::~VoERTP_RTCPImpl() { 44 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1), 45 "VoERTP_RTCPImpl::~VoERTP_RTCPImpl() - dtor"); 46} 47 48int VoERTP_RTCPImpl::SetLocalSSRC(int channel, unsigned int ssrc) { 49 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 50 "SetLocalSSRC(channel=%d, %lu)", channel, ssrc); 51 if (!_shared->statistics().Initialized()) { 52 _shared->SetLastError(VE_NOT_INITED, kTraceError); 53 return -1; 54 } 55 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 56 voe::Channel* channelPtr = ch.channel(); 57 if (channelPtr == NULL) { 58 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 59 "SetLocalSSRC() failed to locate channel"); 60 return -1; 61 } 62 return channelPtr->SetLocalSSRC(ssrc); 63} 64 65int VoERTP_RTCPImpl::GetLocalSSRC(int channel, unsigned int& ssrc) { 66 if (!_shared->statistics().Initialized()) { 67 _shared->SetLastError(VE_NOT_INITED, kTraceError); 68 return -1; 69 } 70 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 71 voe::Channel* channelPtr = ch.channel(); 72 if (channelPtr == NULL) { 73 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 74 "GetLocalSSRC() failed to locate channel"); 75 return -1; 76 } 77 return channelPtr->GetLocalSSRC(ssrc); 78} 79 80int VoERTP_RTCPImpl::GetRemoteSSRC(int channel, unsigned int& ssrc) { 81 if (!_shared->statistics().Initialized()) { 82 _shared->SetLastError(VE_NOT_INITED, kTraceError); 83 return -1; 84 } 85 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 86 voe::Channel* channelPtr = ch.channel(); 87 if (channelPtr == NULL) { 88 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 89 "GetRemoteSSRC() failed to locate channel"); 90 return -1; 91 } 92 return channelPtr->GetRemoteSSRC(ssrc); 93} 94 95int VoERTP_RTCPImpl::SetSendAudioLevelIndicationStatus(int channel, 96 bool enable, 97 unsigned char id) { 98 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 99 "SetSendAudioLevelIndicationStatus(channel=%d, enable=%d," 100 " ID=%u)", 101 channel, enable, id); 102 if (!_shared->statistics().Initialized()) { 103 _shared->SetLastError(VE_NOT_INITED, kTraceError); 104 return -1; 105 } 106 if (enable && (id < kVoiceEngineMinRtpExtensionId || 107 id > kVoiceEngineMaxRtpExtensionId)) { 108 // [RFC5285] The 4-bit id is the local identifier of this element in 109 // the range 1-14 inclusive. 110 _shared->SetLastError( 111 VE_INVALID_ARGUMENT, kTraceError, 112 "SetSendAudioLevelIndicationStatus() invalid ID parameter"); 113 return -1; 114 } 115 116 // Set state and id for the specified channel. 117 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 118 voe::Channel* channelPtr = ch.channel(); 119 if (channelPtr == NULL) { 120 _shared->SetLastError( 121 VE_CHANNEL_NOT_VALID, kTraceError, 122 "SetSendAudioLevelIndicationStatus() failed to locate channel"); 123 return -1; 124 } 125 return channelPtr->SetSendAudioLevelIndicationStatus(enable, id); 126} 127 128int VoERTP_RTCPImpl::SetReceiveAudioLevelIndicationStatus(int channel, 129 bool enable, 130 unsigned char id) { 131 WEBRTC_TRACE( 132 kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 133 "SetReceiveAudioLevelIndicationStatus(channel=%d, enable=%d, id=%u)", 134 channel, enable, id); 135 if (!_shared->statistics().Initialized()) { 136 _shared->SetLastError(VE_NOT_INITED, kTraceError); 137 return -1; 138 } 139 if (enable && (id < kVoiceEngineMinRtpExtensionId || 140 id > kVoiceEngineMaxRtpExtensionId)) { 141 // [RFC5285] The 4-bit id is the local identifier of this element in 142 // the range 1-14 inclusive. 143 _shared->SetLastError( 144 VE_INVALID_ARGUMENT, kTraceError, 145 "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter"); 146 return -1; 147 } 148 // Set state and id for the specified channel. 149 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 150 voe::Channel* channel_ptr = ch.channel(); 151 if (channel_ptr == NULL) { 152 _shared->SetLastError( 153 VE_CHANNEL_NOT_VALID, kTraceError, 154 "SetReceiveAudioLevelIndicationStatus() failed to locate channel"); 155 return -1; 156 } 157 return channel_ptr->SetReceiveAudioLevelIndicationStatus(enable, id); 158} 159 160int VoERTP_RTCPImpl::SetSendAbsoluteSenderTimeStatus(int channel, 161 bool enable, 162 unsigned char id) { 163 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 164 "SetSendAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)", 165 channel, enable, id); 166 if (!_shared->statistics().Initialized()) { 167 _shared->SetLastError(VE_NOT_INITED, kTraceError); 168 return -1; 169 } 170 if (enable && (id < kVoiceEngineMinRtpExtensionId || 171 id > kVoiceEngineMaxRtpExtensionId)) { 172 // [RFC5285] The 4-bit id is the local identifier of this element in 173 // the range 1-14 inclusive. 174 _shared->SetLastError( 175 VE_INVALID_ARGUMENT, kTraceError, 176 "SetSendAbsoluteSenderTimeStatus() invalid id parameter"); 177 return -1; 178 } 179 // Set state and id for the specified channel. 180 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 181 voe::Channel* channelPtr = ch.channel(); 182 if (channelPtr == NULL) { 183 _shared->SetLastError( 184 VE_CHANNEL_NOT_VALID, kTraceError, 185 "SetSendAbsoluteSenderTimeStatus() failed to locate channel"); 186 return -1; 187 } 188 return channelPtr->SetSendAbsoluteSenderTimeStatus(enable, id); 189} 190 191int VoERTP_RTCPImpl::SetReceiveAbsoluteSenderTimeStatus(int channel, 192 bool enable, 193 unsigned char id) { 194 WEBRTC_TRACE( 195 kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 196 "SetReceiveAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)", 197 channel, enable, id); 198 if (!_shared->statistics().Initialized()) { 199 _shared->SetLastError(VE_NOT_INITED, kTraceError); 200 return -1; 201 } 202 if (enable && (id < kVoiceEngineMinRtpExtensionId || 203 id > kVoiceEngineMaxRtpExtensionId)) { 204 // [RFC5285] The 4-bit id is the local identifier of this element in 205 // the range 1-14 inclusive. 206 _shared->SetLastError( 207 VE_INVALID_ARGUMENT, kTraceError, 208 "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter"); 209 return -1; 210 } 211 // Set state and id for the specified channel. 212 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 213 voe::Channel* channelPtr = ch.channel(); 214 if (channelPtr == NULL) { 215 _shared->SetLastError( 216 VE_CHANNEL_NOT_VALID, kTraceError, 217 "SetReceiveAbsoluteSenderTimeStatus() failed to locate channel"); 218 return -1; 219 } 220 return channelPtr->SetReceiveAbsoluteSenderTimeStatus(enable, id); 221} 222 223int VoERTP_RTCPImpl::SetRTCPStatus(int channel, bool enable) { 224 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 225 "SetRTCPStatus(channel=%d, enable=%d)", channel, enable); 226 if (!_shared->statistics().Initialized()) { 227 _shared->SetLastError(VE_NOT_INITED, kTraceError); 228 return -1; 229 } 230 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 231 voe::Channel* channelPtr = ch.channel(); 232 if (channelPtr == NULL) { 233 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 234 "SetRTCPStatus() failed to locate channel"); 235 return -1; 236 } 237 channelPtr->SetRTCPStatus(enable); 238 return 0; 239} 240 241int VoERTP_RTCPImpl::GetRTCPStatus(int channel, bool& enabled) { 242 if (!_shared->statistics().Initialized()) { 243 _shared->SetLastError(VE_NOT_INITED, kTraceError); 244 return -1; 245 } 246 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 247 voe::Channel* channelPtr = ch.channel(); 248 if (channelPtr == NULL) { 249 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 250 "GetRTCPStatus() failed to locate channel"); 251 return -1; 252 } 253 return channelPtr->GetRTCPStatus(enabled); 254} 255 256int VoERTP_RTCPImpl::SetRTCP_CNAME(int channel, const char cName[256]) { 257 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 258 "SetRTCP_CNAME(channel=%d, cName=%s)", channel, cName); 259 if (!_shared->statistics().Initialized()) { 260 _shared->SetLastError(VE_NOT_INITED, kTraceError); 261 return -1; 262 } 263 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 264 voe::Channel* channelPtr = ch.channel(); 265 if (channelPtr == NULL) { 266 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 267 "SetRTCP_CNAME() failed to locate channel"); 268 return -1; 269 } 270 return channelPtr->SetRTCP_CNAME(cName); 271} 272 273int VoERTP_RTCPImpl::GetRemoteRTCP_CNAME(int channel, char cName[256]) { 274 if (!_shared->statistics().Initialized()) { 275 _shared->SetLastError(VE_NOT_INITED, kTraceError); 276 return -1; 277 } 278 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 279 voe::Channel* channelPtr = ch.channel(); 280 if (channelPtr == NULL) { 281 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 282 "GetRemoteRTCP_CNAME() failed to locate channel"); 283 return -1; 284 } 285 return channelPtr->GetRemoteRTCP_CNAME(cName); 286} 287 288int VoERTP_RTCPImpl::GetRemoteRTCPData( 289 int channel, 290 unsigned int& NTPHigh, // from sender info in SR 291 unsigned int& NTPLow, // from sender info in SR 292 unsigned int& timestamp, // from sender info in SR 293 unsigned int& playoutTimestamp, // derived locally 294 unsigned int* jitter, // from report block 1 in SR/RR 295 unsigned short* fractionLost) // from report block 1 in SR/RR 296{ 297 if (!_shared->statistics().Initialized()) { 298 _shared->SetLastError(VE_NOT_INITED, kTraceError); 299 return -1; 300 } 301 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 302 voe::Channel* channelPtr = ch.channel(); 303 if (channelPtr == NULL) { 304 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 305 "GetRemoteRTCP_CNAME() failed to locate channel"); 306 return -1; 307 } 308 return channelPtr->GetRemoteRTCPData(NTPHigh, NTPLow, timestamp, 309 playoutTimestamp, jitter, fractionLost); 310} 311 312int VoERTP_RTCPImpl::GetRTPStatistics(int channel, 313 unsigned int& averageJitterMs, 314 unsigned int& maxJitterMs, 315 unsigned int& discardedPackets) { 316 if (!_shared->statistics().Initialized()) { 317 _shared->SetLastError(VE_NOT_INITED, kTraceError); 318 return -1; 319 } 320 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 321 voe::Channel* channelPtr = ch.channel(); 322 if (channelPtr == NULL) { 323 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 324 "GetRTPStatistics() failed to locate channel"); 325 return -1; 326 } 327 return channelPtr->GetRTPStatistics(averageJitterMs, maxJitterMs, 328 discardedPackets); 329} 330 331int VoERTP_RTCPImpl::GetRTCPStatistics(int channel, CallStatistics& stats) { 332 if (!_shared->statistics().Initialized()) { 333 _shared->SetLastError(VE_NOT_INITED, kTraceError); 334 return -1; 335 } 336 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 337 voe::Channel* channelPtr = ch.channel(); 338 if (channelPtr == NULL) { 339 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 340 "GetRTPStatistics() failed to locate channel"); 341 return -1; 342 } 343 return channelPtr->GetRTPStatistics(stats); 344} 345 346int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks( 347 int channel, std::vector<ReportBlock>* report_blocks) { 348 if (!_shared->statistics().Initialized()) { 349 _shared->SetLastError(VE_NOT_INITED, kTraceError); 350 return -1; 351 } 352 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 353 voe::Channel* channel_ptr = ch.channel(); 354 if (channel_ptr == NULL) { 355 _shared->SetLastError( 356 VE_CHANNEL_NOT_VALID, kTraceError, 357 "GetRemoteRTCPReportBlocks() failed to locate channel"); 358 return -1; 359 } 360 return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks); 361} 362 363int VoERTP_RTCPImpl::SetREDStatus(int channel, 364 bool enable, 365 int redPayloadtype) { 366 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 367 "SetREDStatus(channel=%d, enable=%d, redPayloadtype=%d)", 368 channel, enable, redPayloadtype); 369#ifdef WEBRTC_CODEC_RED 370 if (!_shared->statistics().Initialized()) { 371 _shared->SetLastError(VE_NOT_INITED, kTraceError); 372 return -1; 373 } 374 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 375 voe::Channel* channelPtr = ch.channel(); 376 if (channelPtr == NULL) { 377 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 378 "SetREDStatus() failed to locate channel"); 379 return -1; 380 } 381 return channelPtr->SetREDStatus(enable, redPayloadtype); 382#else 383 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, 384 "SetREDStatus() RED is not supported"); 385 return -1; 386#endif 387} 388 389int VoERTP_RTCPImpl::GetREDStatus(int channel, 390 bool& enabled, 391 int& redPayloadtype) { 392#ifdef WEBRTC_CODEC_RED 393 if (!_shared->statistics().Initialized()) { 394 _shared->SetLastError(VE_NOT_INITED, kTraceError); 395 return -1; 396 } 397 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 398 voe::Channel* channelPtr = ch.channel(); 399 if (channelPtr == NULL) { 400 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 401 "GetREDStatus() failed to locate channel"); 402 return -1; 403 } 404 return channelPtr->GetREDStatus(enabled, redPayloadtype); 405#else 406 _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError, 407 "GetREDStatus() RED is not supported"); 408 return -1; 409#endif 410} 411 412int VoERTP_RTCPImpl::SetNACKStatus(int channel, bool enable, int maxNoPackets) { 413 WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), 414 "SetNACKStatus(channel=%d, enable=%d, maxNoPackets=%d)", channel, 415 enable, maxNoPackets); 416 417 voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel); 418 voe::Channel* channelPtr = ch.channel(); 419 if (channelPtr == NULL) { 420 _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, 421 "SetNACKStatus() failed to locate channel"); 422 return -1; 423 } 424 channelPtr->SetNACKStatus(enable, maxNoPackets); 425 return 0; 426} 427 428#endif // #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API 429 430} // namespace webrtc 431