channel.cc revision 0870f02cdbcce7de8c6a4dceb6d1678c2c6c518f
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 "channel.h" 12 13#include "audio_device.h" 14#include "audio_frame_operations.h" 15#include "audio_processing.h" 16#include "critical_section_wrapper.h" 17#include "logging.h" 18#include "output_mixer.h" 19#include "process_thread.h" 20#include "rtp_dump.h" 21#include "statistics.h" 22#include "trace.h" 23#include "transmit_mixer.h" 24#include "utility.h" 25#include "voe_base.h" 26#include "voe_external_media.h" 27#include "voe_rtp_rtcp.h" 28 29#if defined(_WIN32) 30#include <Qos.h> 31#endif 32 33namespace webrtc { 34namespace voe { 35 36WebRtc_Word32 37Channel::SendData(FrameType frameType, 38 WebRtc_UWord8 payloadType, 39 WebRtc_UWord32 timeStamp, 40 const WebRtc_UWord8* payloadData, 41 WebRtc_UWord16 payloadSize, 42 const RTPFragmentationHeader* fragmentation) 43{ 44 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 45 "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," 46 " payloadSize=%u, fragmentation=0x%x)", 47 frameType, payloadType, timeStamp, payloadSize, fragmentation); 48 49 if (_includeAudioLevelIndication) 50 { 51 assert(_rtpAudioProc.get() != NULL); 52 // Store current audio level in the RTP/RTCP module. 53 // The level will be used in combination with voice-activity state 54 // (frameType) to add an RTP header extension 55 _rtpRtcpModule->SetAudioLevel(_rtpAudioProc->level_estimator()->RMS()); 56 } 57 58 // Push data from ACM to RTP/RTCP-module to deliver audio frame for 59 // packetization. 60 // This call will trigger Transport::SendPacket() from the RTP/RTCP module. 61 if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, 62 payloadType, 63 timeStamp, 64 // Leaving the time when this frame was 65 // received from the capture device as 66 // undefined for voice for now. 67 -1, 68 payloadData, 69 payloadSize, 70 fragmentation) == -1) 71 { 72 _engineStatisticsPtr->SetLastError( 73 VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 74 "Channel::SendData() failed to send data to RTP/RTCP module"); 75 return -1; 76 } 77 78 _lastLocalTimeStamp = timeStamp; 79 _lastPayloadType = payloadType; 80 81 return 0; 82} 83 84WebRtc_Word32 85Channel::InFrameType(WebRtc_Word16 frameType) 86{ 87 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 88 "Channel::InFrameType(frameType=%d)", frameType); 89 90 CriticalSectionScoped cs(&_callbackCritSect); 91 // 1 indicates speech 92 _sendFrameType = (frameType == 1) ? 1 : 0; 93 return 0; 94} 95 96#ifdef WEBRTC_DTMF_DETECTION 97int 98Channel::IncomingDtmf(const WebRtc_UWord8 digitDtmf, const bool end) 99{ 100 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 101 "Channel::IncomingDtmf(digitDtmf=%u, end=%d)", 102 digitDtmf, end); 103 104 if (digitDtmf != 999) 105 { 106 CriticalSectionScoped cs(&_callbackCritSect); 107 if (_telephoneEventDetectionPtr) 108 { 109 _telephoneEventDetectionPtr->OnReceivedTelephoneEventInband( 110 _channelId, digitDtmf, end); 111 } 112 } 113 114 return 0; 115} 116#endif 117 118WebRtc_Word32 119Channel::OnRxVadDetected(const int vadDecision) 120{ 121 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 122 "Channel::OnRxVadDetected(vadDecision=%d)", vadDecision); 123 124 CriticalSectionScoped cs(&_callbackCritSect); 125 if (_rxVadObserverPtr) 126 { 127 _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); 128 } 129 130 return 0; 131} 132 133int 134Channel::SendPacket(int channel, const void *data, int len) 135{ 136 channel = VoEChannelId(channel); 137 assert(channel == _channelId); 138 139 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 140 "Channel::SendPacket(channel=%d, len=%d)", channel, len); 141 142 if (_transportPtr == NULL) 143 { 144 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 145 "Channel::SendPacket() failed to send RTP packet due to" 146 " invalid transport object"); 147 return -1; 148 } 149 150 // Insert extra RTP packet using if user has called the InsertExtraRTPPacket 151 // API 152 if (_insertExtraRTPPacket) 153 { 154 WebRtc_UWord8* rtpHdr = (WebRtc_UWord8*)data; 155 WebRtc_UWord8 M_PT(0); 156 if (_extraMarkerBit) 157 { 158 M_PT = 0x80; // set the M-bit 159 } 160 M_PT += _extraPayloadType; // set the payload type 161 *(++rtpHdr) = M_PT; // modify the M|PT-byte within the RTP header 162 _insertExtraRTPPacket = false; // insert one packet only 163 } 164 165 WebRtc_UWord8* bufferToSendPtr = (WebRtc_UWord8*)data; 166 WebRtc_Word32 bufferLength = len; 167 168 // Dump the RTP packet to a file (if RTP dump is enabled). 169 if (_rtpDumpOut.DumpPacket((const WebRtc_UWord8*)data, len) == -1) 170 { 171 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 172 VoEId(_instanceId,_channelId), 173 "Channel::SendPacket() RTP dump to output file failed"); 174 } 175 176 // SRTP or External encryption 177 if (_encrypting) 178 { 179 CriticalSectionScoped cs(&_callbackCritSect); 180 181 if (_encryptionPtr) 182 { 183 if (!_encryptionRTPBufferPtr) 184 { 185 // Allocate memory for encryption buffer one time only 186 _encryptionRTPBufferPtr = 187 new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 188 memset(_encryptionRTPBufferPtr, 0, 189 kVoiceEngineMaxIpPacketSizeBytes); 190 } 191 192 // Perform encryption (SRTP or external) 193 WebRtc_Word32 encryptedBufferLength = 0; 194 _encryptionPtr->encrypt(_channelId, 195 bufferToSendPtr, 196 _encryptionRTPBufferPtr, 197 bufferLength, 198 (int*)&encryptedBufferLength); 199 if (encryptedBufferLength <= 0) 200 { 201 _engineStatisticsPtr->SetLastError( 202 VE_ENCRYPTION_FAILED, 203 kTraceError, "Channel::SendPacket() encryption failed"); 204 return -1; 205 } 206 207 // Replace default data buffer with encrypted buffer 208 bufferToSendPtr = _encryptionRTPBufferPtr; 209 bufferLength = encryptedBufferLength; 210 } 211 } 212 213 // Packet transmission using WebRtc socket transport 214 if (!_externalTransport) 215 { 216 int n = _transportPtr->SendPacket(channel, bufferToSendPtr, 217 bufferLength); 218 if (n < 0) 219 { 220 WEBRTC_TRACE(kTraceError, kTraceVoice, 221 VoEId(_instanceId,_channelId), 222 "Channel::SendPacket() RTP transmission using WebRtc" 223 " sockets failed"); 224 return -1; 225 } 226 return n; 227 } 228 229 // Packet transmission using external transport transport 230 { 231 CriticalSectionScoped cs(&_callbackCritSect); 232 233 int n = _transportPtr->SendPacket(channel, 234 bufferToSendPtr, 235 bufferLength); 236 if (n < 0) 237 { 238 WEBRTC_TRACE(kTraceError, kTraceVoice, 239 VoEId(_instanceId,_channelId), 240 "Channel::SendPacket() RTP transmission using external" 241 " transport failed"); 242 return -1; 243 } 244 return n; 245 } 246} 247 248int 249Channel::SendRTCPPacket(int channel, const void *data, int len) 250{ 251 channel = VoEChannelId(channel); 252 assert(channel == _channelId); 253 254 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 255 "Channel::SendRTCPPacket(channel=%d, len=%d)", channel, len); 256 257 { 258 CriticalSectionScoped cs(&_callbackCritSect); 259 if (_transportPtr == NULL) 260 { 261 WEBRTC_TRACE(kTraceError, kTraceVoice, 262 VoEId(_instanceId,_channelId), 263 "Channel::SendRTCPPacket() failed to send RTCP packet" 264 " due to invalid transport object"); 265 return -1; 266 } 267 } 268 269 WebRtc_UWord8* bufferToSendPtr = (WebRtc_UWord8*)data; 270 WebRtc_Word32 bufferLength = len; 271 272 // Dump the RTCP packet to a file (if RTP dump is enabled). 273 if (_rtpDumpOut.DumpPacket((const WebRtc_UWord8*)data, len) == -1) 274 { 275 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 276 VoEId(_instanceId,_channelId), 277 "Channel::SendPacket() RTCP dump to output file failed"); 278 } 279 280 // SRTP or External encryption 281 if (_encrypting) 282 { 283 CriticalSectionScoped cs(&_callbackCritSect); 284 285 if (_encryptionPtr) 286 { 287 if (!_encryptionRTCPBufferPtr) 288 { 289 // Allocate memory for encryption buffer one time only 290 _encryptionRTCPBufferPtr = 291 new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 292 } 293 294 // Perform encryption (SRTP or external). 295 WebRtc_Word32 encryptedBufferLength = 0; 296 _encryptionPtr->encrypt_rtcp(_channelId, 297 bufferToSendPtr, 298 _encryptionRTCPBufferPtr, 299 bufferLength, 300 (int*)&encryptedBufferLength); 301 if (encryptedBufferLength <= 0) 302 { 303 _engineStatisticsPtr->SetLastError( 304 VE_ENCRYPTION_FAILED, kTraceError, 305 "Channel::SendRTCPPacket() encryption failed"); 306 return -1; 307 } 308 309 // Replace default data buffer with encrypted buffer 310 bufferToSendPtr = _encryptionRTCPBufferPtr; 311 bufferLength = encryptedBufferLength; 312 } 313 } 314 315 // Packet transmission using WebRtc socket transport 316 if (!_externalTransport) 317 { 318 int n = _transportPtr->SendRTCPPacket(channel, 319 bufferToSendPtr, 320 bufferLength); 321 if (n < 0) 322 { 323 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 324 VoEId(_instanceId,_channelId), 325 "Channel::SendRTCPPacket() transmission using WebRtc" 326 " sockets failed"); 327 return -1; 328 } 329 return n; 330 } 331 332 // Packet transmission using external transport transport 333 { 334 CriticalSectionScoped cs(&_callbackCritSect); 335 if (_transportPtr == NULL) 336 { 337 return -1; 338 } 339 int n = _transportPtr->SendRTCPPacket(channel, 340 bufferToSendPtr, 341 bufferLength); 342 if (n < 0) 343 { 344 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 345 VoEId(_instanceId,_channelId), 346 "Channel::SendRTCPPacket() transmission using external" 347 " transport failed"); 348 return -1; 349 } 350 return n; 351 } 352 353 return len; 354} 355 356void 357Channel::IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket, 358 const WebRtc_Word32 rtpPacketLength, 359 const char* fromIP, 360 const WebRtc_UWord16 fromPort) 361{ 362 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 363 "Channel::IncomingRTPPacket(rtpPacketLength=%d," 364 " fromIP=%s, fromPort=%u)", 365 rtpPacketLength, fromIP, fromPort); 366 367 // Store playout timestamp for the received RTP packet 368 // to be used for upcoming delay estimations 369 WebRtc_UWord32 playoutTimestamp(0); 370 if (GetPlayoutTimeStamp(playoutTimestamp) == 0) 371 { 372 _playoutTimeStampRTP = playoutTimestamp; 373 } 374 375 WebRtc_UWord8* rtpBufferPtr = (WebRtc_UWord8*)incomingRtpPacket; 376 WebRtc_Word32 rtpBufferLength = rtpPacketLength; 377 378 // SRTP or External decryption 379 if (_decrypting) 380 { 381 CriticalSectionScoped cs(&_callbackCritSect); 382 383 if (_encryptionPtr) 384 { 385 if (!_decryptionRTPBufferPtr) 386 { 387 // Allocate memory for decryption buffer one time only 388 _decryptionRTPBufferPtr = 389 new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 390 } 391 392 // Perform decryption (SRTP or external) 393 WebRtc_Word32 decryptedBufferLength = 0; 394 _encryptionPtr->decrypt(_channelId, 395 rtpBufferPtr, 396 _decryptionRTPBufferPtr, 397 rtpBufferLength, 398 (int*)&decryptedBufferLength); 399 if (decryptedBufferLength <= 0) 400 { 401 _engineStatisticsPtr->SetLastError( 402 VE_DECRYPTION_FAILED, kTraceError, 403 "Channel::IncomingRTPPacket() decryption failed"); 404 return; 405 } 406 407 // Replace default data buffer with decrypted buffer 408 rtpBufferPtr = _decryptionRTPBufferPtr; 409 rtpBufferLength = decryptedBufferLength; 410 } 411 } 412 413 // Dump the RTP packet to a file (if RTP dump is enabled). 414 if (_rtpDumpIn.DumpPacket(rtpBufferPtr, 415 (WebRtc_UWord16)rtpBufferLength) == -1) 416 { 417 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 418 VoEId(_instanceId,_channelId), 419 "Channel::SendPacket() RTP dump to input file failed"); 420 } 421 422 // Deliver RTP packet to RTP/RTCP module for parsing 423 // The packet will be pushed back to the channel thru the 424 // OnReceivedPayloadData callback so we don't push it to the ACM here 425 if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtpBufferPtr, 426 (WebRtc_UWord16)rtpBufferLength) == -1) 427 { 428 _engineStatisticsPtr->SetLastError( 429 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 430 "Channel::IncomingRTPPacket() RTP packet is invalid"); 431 return; 432 } 433} 434 435void 436Channel::IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket, 437 const WebRtc_Word32 rtcpPacketLength, 438 const char* fromIP, 439 const WebRtc_UWord16 fromPort) 440{ 441 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 442 "Channel::IncomingRTCPPacket(rtcpPacketLength=%d, fromIP=%s," 443 " fromPort=%u)", 444 rtcpPacketLength, fromIP, fromPort); 445 446 // Temporary buffer pointer and size for decryption 447 WebRtc_UWord8* rtcpBufferPtr = (WebRtc_UWord8*)incomingRtcpPacket; 448 WebRtc_Word32 rtcpBufferLength = rtcpPacketLength; 449 450 // Store playout timestamp for the received RTCP packet 451 // which will be read by the GetRemoteRTCPData API 452 WebRtc_UWord32 playoutTimestamp(0); 453 if (GetPlayoutTimeStamp(playoutTimestamp) == 0) 454 { 455 _playoutTimeStampRTCP = playoutTimestamp; 456 } 457 458 // SRTP or External decryption 459 if (_decrypting) 460 { 461 CriticalSectionScoped cs(&_callbackCritSect); 462 463 if (_encryptionPtr) 464 { 465 if (!_decryptionRTCPBufferPtr) 466 { 467 // Allocate memory for decryption buffer one time only 468 _decryptionRTCPBufferPtr = 469 new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 470 } 471 472 // Perform decryption (SRTP or external). 473 WebRtc_Word32 decryptedBufferLength = 0; 474 _encryptionPtr->decrypt_rtcp(_channelId, 475 rtcpBufferPtr, 476 _decryptionRTCPBufferPtr, 477 rtcpBufferLength, 478 (int*)&decryptedBufferLength); 479 if (decryptedBufferLength <= 0) 480 { 481 _engineStatisticsPtr->SetLastError( 482 VE_DECRYPTION_FAILED, kTraceError, 483 "Channel::IncomingRTCPPacket() decryption failed"); 484 return; 485 } 486 487 // Replace default data buffer with decrypted buffer 488 rtcpBufferPtr = _decryptionRTCPBufferPtr; 489 rtcpBufferLength = decryptedBufferLength; 490 } 491 } 492 493 // Dump the RTCP packet to a file (if RTP dump is enabled). 494 if (_rtpDumpIn.DumpPacket(rtcpBufferPtr, 495 (WebRtc_UWord16)rtcpBufferLength) == -1) 496 { 497 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 498 VoEId(_instanceId,_channelId), 499 "Channel::SendPacket() RTCP dump to input file failed"); 500 } 501 502 // Deliver RTCP packet to RTP/RTCP module for parsing 503 if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtcpBufferPtr, 504 (WebRtc_UWord16)rtcpBufferLength) == -1) 505 { 506 _engineStatisticsPtr->SetLastError( 507 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 508 "Channel::IncomingRTPPacket() RTCP packet is invalid"); 509 return; 510 } 511} 512 513void 514Channel::OnReceivedTelephoneEvent(const WebRtc_Word32 id, 515 const WebRtc_UWord8 event, 516 const bool endOfEvent) 517{ 518 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 519 "Channel::OnReceivedTelephoneEvent(id=%d, event=%u," 520 " endOfEvent=%d)", id, event, endOfEvent); 521 522#ifdef WEBRTC_DTMF_DETECTION 523 if (_outOfBandTelephoneEventDetecion) 524 { 525 CriticalSectionScoped cs(&_callbackCritSect); 526 527 if (_telephoneEventDetectionPtr) 528 { 529 _telephoneEventDetectionPtr->OnReceivedTelephoneEventOutOfBand( 530 _channelId, event, endOfEvent); 531 } 532 } 533#endif 534} 535 536void 537Channel::OnPlayTelephoneEvent(const WebRtc_Word32 id, 538 const WebRtc_UWord8 event, 539 const WebRtc_UWord16 lengthMs, 540 const WebRtc_UWord8 volume) 541{ 542 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 543 "Channel::OnPlayTelephoneEvent(id=%d, event=%u, lengthMs=%u," 544 " volume=%u)", id, event, lengthMs, volume); 545 546 if (!_playOutbandDtmfEvent || (event > 15)) 547 { 548 // Ignore callback since feedback is disabled or event is not a 549 // Dtmf tone event. 550 return; 551 } 552 553 assert(_outputMixerPtr != NULL); 554 555 // Start playing out the Dtmf tone (if playout is enabled). 556 // Reduce length of tone with 80ms to the reduce risk of echo. 557 _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); 558} 559 560void 561Channel::OnIncomingSSRCChanged(const WebRtc_Word32 id, 562 const WebRtc_UWord32 SSRC) 563{ 564 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 565 "Channel::OnIncomingSSRCChanged(id=%d, SSRC=%d)", 566 id, SSRC); 567 568 WebRtc_Word32 channel = VoEChannelId(id); 569 assert(channel == _channelId); 570 571 // Reset RTP-module counters since a new incoming RTP stream is detected 572 _rtpRtcpModule->ResetReceiveDataCountersRTP(); 573 _rtpRtcpModule->ResetStatisticsRTP(); 574 575 if (_rtpObserver) 576 { 577 CriticalSectionScoped cs(&_callbackCritSect); 578 579 if (_rtpObserverPtr) 580 { 581 // Send new SSRC to registered observer using callback 582 _rtpObserverPtr->OnIncomingSSRCChanged(channel, SSRC); 583 } 584 } 585} 586 587void Channel::OnIncomingCSRCChanged(const WebRtc_Word32 id, 588 const WebRtc_UWord32 CSRC, 589 const bool added) 590{ 591 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 592 "Channel::OnIncomingCSRCChanged(id=%d, CSRC=%d, added=%d)", 593 id, CSRC, added); 594 595 WebRtc_Word32 channel = VoEChannelId(id); 596 assert(channel == _channelId); 597 598 if (_rtpObserver) 599 { 600 CriticalSectionScoped cs(&_callbackCritSect); 601 602 if (_rtpObserverPtr) 603 { 604 _rtpObserverPtr->OnIncomingCSRCChanged(channel, CSRC, added); 605 } 606 } 607} 608 609void 610Channel::OnApplicationDataReceived(const WebRtc_Word32 id, 611 const WebRtc_UWord8 subType, 612 const WebRtc_UWord32 name, 613 const WebRtc_UWord16 length, 614 const WebRtc_UWord8* data) 615{ 616 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 617 "Channel::OnApplicationDataReceived(id=%d, subType=%u," 618 " name=%u, length=%u)", 619 id, subType, name, length); 620 621 WebRtc_Word32 channel = VoEChannelId(id); 622 assert(channel == _channelId); 623 624 if (_rtcpObserver) 625 { 626 CriticalSectionScoped cs(&_callbackCritSect); 627 628 if (_rtcpObserverPtr) 629 { 630 _rtcpObserverPtr->OnApplicationDataReceived(channel, 631 subType, 632 name, 633 data, 634 length); 635 } 636 } 637} 638 639WebRtc_Word32 640Channel::OnInitializeDecoder( 641 const WebRtc_Word32 id, 642 const WebRtc_Word8 payloadType, 643 const char payloadName[RTP_PAYLOAD_NAME_SIZE], 644 const int frequency, 645 const WebRtc_UWord8 channels, 646 const WebRtc_UWord32 rate) 647{ 648 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 649 "Channel::OnInitializeDecoder(id=%d, payloadType=%d, " 650 "payloadName=%s, frequency=%u, channels=%u, rate=%u)", 651 id, payloadType, payloadName, frequency, channels, rate); 652 653 assert(VoEChannelId(id) == _channelId); 654 655 CodecInst receiveCodec = {0}; 656 CodecInst dummyCodec = {0}; 657 658 receiveCodec.pltype = payloadType; 659 receiveCodec.plfreq = frequency; 660 receiveCodec.channels = channels; 661 receiveCodec.rate = rate; 662 strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 663 664 _audioCodingModule.Codec(payloadName, dummyCodec, frequency, channels); 665 receiveCodec.pacsize = dummyCodec.pacsize; 666 667 // Register the new codec to the ACM 668 if (_audioCodingModule.RegisterReceiveCodec(receiveCodec) == -1) 669 { 670 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 671 VoEId(_instanceId, _channelId), 672 "Channel::OnInitializeDecoder() invalid codec (" 673 "pt=%d, name=%s) received - 1", payloadType, payloadName); 674 _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); 675 return -1; 676 } 677 678 return 0; 679} 680 681void 682Channel::OnPacketTimeout(const WebRtc_Word32 id) 683{ 684 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 685 "Channel::OnPacketTimeout(id=%d)", id); 686 687 CriticalSectionScoped cs(_callbackCritSectPtr); 688 if (_voiceEngineObserverPtr) 689 { 690 if (_receiving || _externalTransport) 691 { 692 WebRtc_Word32 channel = VoEChannelId(id); 693 assert(channel == _channelId); 694 // Ensure that next OnReceivedPacket() callback will trigger 695 // a VE_PACKET_RECEIPT_RESTARTED callback. 696 _rtpPacketTimedOut = true; 697 // Deliver callback to the observer 698 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 699 VoEId(_instanceId,_channelId), 700 "Channel::OnPacketTimeout() => " 701 "CallbackOnError(VE_RECEIVE_PACKET_TIMEOUT)"); 702 _voiceEngineObserverPtr->CallbackOnError(channel, 703 VE_RECEIVE_PACKET_TIMEOUT); 704 } 705 } 706} 707 708void 709Channel::OnReceivedPacket(const WebRtc_Word32 id, 710 const RtpRtcpPacketType packetType) 711{ 712 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 713 "Channel::OnReceivedPacket(id=%d, packetType=%d)", 714 id, packetType); 715 716 assert(VoEChannelId(id) == _channelId); 717 718 // Notify only for the case when we have restarted an RTP session. 719 if (_rtpPacketTimedOut && (kPacketRtp == packetType)) 720 { 721 CriticalSectionScoped cs(_callbackCritSectPtr); 722 if (_voiceEngineObserverPtr) 723 { 724 WebRtc_Word32 channel = VoEChannelId(id); 725 assert(channel == _channelId); 726 // Reset timeout mechanism 727 _rtpPacketTimedOut = false; 728 // Deliver callback to the observer 729 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 730 VoEId(_instanceId,_channelId), 731 "Channel::OnPacketTimeout() =>" 732 " CallbackOnError(VE_PACKET_RECEIPT_RESTARTED)"); 733 _voiceEngineObserverPtr->CallbackOnError( 734 channel, 735 VE_PACKET_RECEIPT_RESTARTED); 736 } 737 } 738} 739 740void 741Channel::OnPeriodicDeadOrAlive(const WebRtc_Word32 id, 742 const RTPAliveType alive) 743{ 744 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 745 "Channel::OnPeriodicDeadOrAlive(id=%d, alive=%d)", id, alive); 746 747 if (!_connectionObserver) 748 return; 749 750 WebRtc_Word32 channel = VoEChannelId(id); 751 assert(channel == _channelId); 752 753 // Use Alive as default to limit risk of false Dead detections 754 bool isAlive(true); 755 756 // Always mark the connection as Dead when the module reports kRtpDead 757 if (kRtpDead == alive) 758 { 759 isAlive = false; 760 } 761 762 // It is possible that the connection is alive even if no RTP packet has 763 // been received for a long time since the other side might use VAD/DTX 764 // and a low SID-packet update rate. 765 if ((kRtpNoRtp == alive) && _playing) 766 { 767 // Detect Alive for all NetEQ states except for the case when we are 768 // in PLC_CNG state. 769 // PLC_CNG <=> background noise only due to long expand or error. 770 // Note that, the case where the other side stops sending during CNG 771 // state will be detected as Alive. Dead is is not set until after 772 // missing RTCP packets for at least twelve seconds (handled 773 // internally by the RTP/RTCP module). 774 isAlive = (_outputSpeechType != AudioFrame::kPLCCNG); 775 } 776 777 UpdateDeadOrAliveCounters(isAlive); 778 779 // Send callback to the registered observer 780 if (_connectionObserver) 781 { 782 CriticalSectionScoped cs(&_callbackCritSect); 783 if (_connectionObserverPtr) 784 { 785 _connectionObserverPtr->OnPeriodicDeadOrAlive(channel, isAlive); 786 } 787 } 788} 789 790WebRtc_Word32 791Channel::OnReceivedPayloadData(const WebRtc_UWord8* payloadData, 792 const WebRtc_UWord16 payloadSize, 793 const WebRtcRTPHeader* rtpHeader) 794{ 795 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 796 "Channel::OnReceivedPayloadData(payloadSize=%d," 797 " payloadType=%u, audioChannel=%u)", 798 payloadSize, 799 rtpHeader->header.payloadType, 800 rtpHeader->type.Audio.channel); 801 802 _lastRemoteTimeStamp = rtpHeader->header.timestamp; 803 804 if (!_playing) 805 { 806 // Avoid inserting into NetEQ when we are not playing. Count the 807 // packet as discarded. 808 WEBRTC_TRACE(kTraceStream, kTraceVoice, 809 VoEId(_instanceId, _channelId), 810 "received packet is discarded since playing is not" 811 " activated"); 812 _numberOfDiscardedPackets++; 813 return 0; 814 } 815 816 // Push the incoming payload (parsed and ready for decoding) into the ACM 817 if (_audioCodingModule.IncomingPacket(payloadData, 818 payloadSize, 819 *rtpHeader) != 0) 820 { 821 _engineStatisticsPtr->SetLastError( 822 VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 823 "Channel::OnReceivedPayloadData() unable to push data to the ACM"); 824 return -1; 825 } 826 827 // Update the packet delay 828 UpdatePacketDelay(rtpHeader->header.timestamp, 829 rtpHeader->header.sequenceNumber); 830 831 return 0; 832} 833 834WebRtc_Word32 Channel::GetAudioFrame(const WebRtc_Word32 id, 835 AudioFrame& audioFrame) 836{ 837 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 838 "Channel::GetAudioFrame(id=%d)", id); 839 840 // Get 10ms raw PCM data from the ACM (mixer limits output frequency) 841 if (_audioCodingModule.PlayoutData10Ms(audioFrame.sample_rate_hz_, 842 audioFrame) == -1) 843 { 844 WEBRTC_TRACE(kTraceError, kTraceVoice, 845 VoEId(_instanceId,_channelId), 846 "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); 847 // In all likelihood, the audio in this frame is garbage. We return an 848 // error so that the audio mixer module doesn't add it to the mix. As 849 // a result, it won't be played out and the actions skipped here are 850 // irrelevant. 851 return -1; 852 } 853 854 if (_RxVadDetection) 855 { 856 UpdateRxVadDetection(audioFrame); 857 } 858 859 // Convert module ID to internal VoE channel ID 860 audioFrame.id_ = VoEChannelId(audioFrame.id_); 861 // Store speech type for dead-or-alive detection 862 _outputSpeechType = audioFrame.speech_type_; 863 864 // Perform far-end AudioProcessing module processing on the received signal 865 if (_rxApmIsEnabled) 866 { 867 ApmProcessRx(audioFrame); 868 } 869 870 // Output volume scaling 871 if (_outputGain < 0.99f || _outputGain > 1.01f) 872 { 873 AudioFrameOperations::ScaleWithSat(_outputGain, audioFrame); 874 } 875 876 // Scale left and/or right channel(s) if stereo and master balance is 877 // active 878 879 if (_panLeft != 1.0f || _panRight != 1.0f) 880 { 881 if (audioFrame.num_channels_ == 1) 882 { 883 // Emulate stereo mode since panning is active. 884 // The mono signal is copied to both left and right channels here. 885 AudioFrameOperations::MonoToStereo(&audioFrame); 886 } 887 // For true stereo mode (when we are receiving a stereo signal), no 888 // action is needed. 889 890 // Do the panning operation (the audio frame contains stereo at this 891 // stage) 892 AudioFrameOperations::Scale(_panLeft, _panRight, audioFrame); 893 } 894 895 // Mix decoded PCM output with file if file mixing is enabled 896 if (_outputFilePlaying) 897 { 898 MixAudioWithFile(audioFrame, audioFrame.sample_rate_hz_); 899 } 900 901 // Place channel in on-hold state (~muted) if on-hold is activated 902 if (_outputIsOnHold) 903 { 904 AudioFrameOperations::Mute(audioFrame); 905 } 906 907 // External media 908 if (_outputExternalMedia) 909 { 910 CriticalSectionScoped cs(&_callbackCritSect); 911 const bool isStereo = (audioFrame.num_channels_ == 2); 912 if (_outputExternalMediaCallbackPtr) 913 { 914 _outputExternalMediaCallbackPtr->Process( 915 _channelId, 916 kPlaybackPerChannel, 917 (WebRtc_Word16*)audioFrame.data_, 918 audioFrame.samples_per_channel_, 919 audioFrame.sample_rate_hz_, 920 isStereo); 921 } 922 } 923 924 // Record playout if enabled 925 { 926 CriticalSectionScoped cs(&_fileCritSect); 927 928 if (_outputFileRecording && _outputFileRecorderPtr) 929 { 930 _outputFileRecorderPtr->RecordAudioToFile(audioFrame); 931 } 932 } 933 934 // Measure audio level (0-9) 935 _outputAudioLevel.ComputeLevel(audioFrame); 936 937 return 0; 938} 939 940WebRtc_Word32 941Channel::NeededFrequency(const WebRtc_Word32 id) 942{ 943 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 944 "Channel::NeededFrequency(id=%d)", id); 945 946 int highestNeeded = 0; 947 948 // Determine highest needed receive frequency 949 WebRtc_Word32 receiveFrequency = _audioCodingModule.ReceiveFrequency(); 950 951 // Return the bigger of playout and receive frequency in the ACM. 952 if (_audioCodingModule.PlayoutFrequency() > receiveFrequency) 953 { 954 highestNeeded = _audioCodingModule.PlayoutFrequency(); 955 } 956 else 957 { 958 highestNeeded = receiveFrequency; 959 } 960 961 // Special case, if we're playing a file on the playout side 962 // we take that frequency into consideration as well 963 // This is not needed on sending side, since the codec will 964 // limit the spectrum anyway. 965 if (_outputFilePlaying) 966 { 967 CriticalSectionScoped cs(&_fileCritSect); 968 if (_outputFilePlayerPtr && _outputFilePlaying) 969 { 970 if(_outputFilePlayerPtr->Frequency()>highestNeeded) 971 { 972 highestNeeded=_outputFilePlayerPtr->Frequency(); 973 } 974 } 975 } 976 977 return(highestNeeded); 978} 979 980WebRtc_Word32 981Channel::CreateChannel(Channel*& channel, 982 const WebRtc_Word32 channelId, 983 const WebRtc_UWord32 instanceId) 984{ 985 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), 986 "Channel::CreateChannel(channelId=%d, instanceId=%d)", 987 channelId, instanceId); 988 989 channel = new Channel(channelId, instanceId); 990 if (channel == NULL) 991 { 992 WEBRTC_TRACE(kTraceMemory, kTraceVoice, 993 VoEId(instanceId,channelId), 994 "Channel::CreateChannel() unable to allocate memory for" 995 " channel"); 996 return -1; 997 } 998 return 0; 999} 1000 1001void 1002Channel::PlayNotification(const WebRtc_Word32 id, 1003 const WebRtc_UWord32 durationMs) 1004{ 1005 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1006 "Channel::PlayNotification(id=%d, durationMs=%d)", 1007 id, durationMs); 1008 1009 // Not implement yet 1010} 1011 1012void 1013Channel::RecordNotification(const WebRtc_Word32 id, 1014 const WebRtc_UWord32 durationMs) 1015{ 1016 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1017 "Channel::RecordNotification(id=%d, durationMs=%d)", 1018 id, durationMs); 1019 1020 // Not implement yet 1021} 1022 1023void 1024Channel::PlayFileEnded(const WebRtc_Word32 id) 1025{ 1026 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1027 "Channel::PlayFileEnded(id=%d)", id); 1028 1029 if (id == _inputFilePlayerId) 1030 { 1031 CriticalSectionScoped cs(&_fileCritSect); 1032 1033 _inputFilePlaying = false; 1034 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1035 VoEId(_instanceId,_channelId), 1036 "Channel::PlayFileEnded() => input file player module is" 1037 " shutdown"); 1038 } 1039 else if (id == _outputFilePlayerId) 1040 { 1041 CriticalSectionScoped cs(&_fileCritSect); 1042 1043 _outputFilePlaying = false; 1044 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1045 VoEId(_instanceId,_channelId), 1046 "Channel::PlayFileEnded() => output file player module is" 1047 " shutdown"); 1048 } 1049} 1050 1051void 1052Channel::RecordFileEnded(const WebRtc_Word32 id) 1053{ 1054 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1055 "Channel::RecordFileEnded(id=%d)", id); 1056 1057 assert(id == _outputFileRecorderId); 1058 1059 CriticalSectionScoped cs(&_fileCritSect); 1060 1061 _outputFileRecording = false; 1062 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1063 VoEId(_instanceId,_channelId), 1064 "Channel::RecordFileEnded() => output file recorder module is" 1065 " shutdown"); 1066} 1067 1068Channel::Channel(const WebRtc_Word32 channelId, 1069 const WebRtc_UWord32 instanceId) : 1070 _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 1071 _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 1072 _instanceId(instanceId), 1073 _channelId(channelId), 1074 _audioCodingModule(*AudioCodingModule::Create( 1075 VoEModuleId(instanceId, channelId))), 1076#ifndef WEBRTC_EXTERNAL_TRANSPORT 1077 _numSocketThreads(KNumSocketThreads), 1078 _socketTransportModule(*UdpTransport::Create( 1079 VoEModuleId(instanceId, channelId), _numSocketThreads)), 1080#endif 1081#ifdef WEBRTC_SRTP 1082 _srtpModule(*SrtpModule::CreateSrtpModule(VoEModuleId(instanceId, 1083 channelId))), 1084#endif 1085 _rtpDumpIn(*RtpDump::CreateRtpDump()), 1086 _rtpDumpOut(*RtpDump::CreateRtpDump()), 1087 _outputAudioLevel(), 1088 _externalTransport(false), 1089 _inputFilePlayerPtr(NULL), 1090 _outputFilePlayerPtr(NULL), 1091 _outputFileRecorderPtr(NULL), 1092 // Avoid conflict with other channels by adding 1024 - 1026, 1093 // won't use as much as 1024 channels. 1094 _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), 1095 _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), 1096 _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), 1097 _inputFilePlaying(false), 1098 _outputFilePlaying(false), 1099 _outputFileRecording(false), 1100 _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), 1101 _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), 1102 _inputExternalMedia(false), 1103 _outputExternalMedia(false), 1104 _inputExternalMediaCallbackPtr(NULL), 1105 _outputExternalMediaCallbackPtr(NULL), 1106 _encryptionRTPBufferPtr(NULL), 1107 _decryptionRTPBufferPtr(NULL), 1108 _encryptionRTCPBufferPtr(NULL), 1109 _decryptionRTCPBufferPtr(NULL), 1110 _timeStamp(0), // This is just an offset, RTP module will add it's own random offset 1111 _sendTelephoneEventPayloadType(106), 1112 _playoutTimeStampRTP(0), 1113 _playoutTimeStampRTCP(0), 1114 _numberOfDiscardedPackets(0), 1115 _engineStatisticsPtr(NULL), 1116 _outputMixerPtr(NULL), 1117 _transmitMixerPtr(NULL), 1118 _moduleProcessThreadPtr(NULL), 1119 _audioDeviceModulePtr(NULL), 1120 _voiceEngineObserverPtr(NULL), 1121 _callbackCritSectPtr(NULL), 1122 _transportPtr(NULL), 1123 _encryptionPtr(NULL), 1124 _rtpAudioProc(NULL), 1125 _rxAudioProcessingModulePtr(NULL), 1126#ifdef WEBRTC_DTMF_DETECTION 1127 _telephoneEventDetectionPtr(NULL), 1128#endif 1129 _rxVadObserverPtr(NULL), 1130 _oldVadDecision(-1), 1131 _sendFrameType(0), 1132 _rtpObserverPtr(NULL), 1133 _rtcpObserverPtr(NULL), 1134 _outputIsOnHold(false), 1135 _externalPlayout(false), 1136 _inputIsOnHold(false), 1137 _playing(false), 1138 _sending(false), 1139 _receiving(false), 1140 _mixFileWithMicrophone(false), 1141 _rtpObserver(false), 1142 _rtcpObserver(false), 1143 _mute(false), 1144 _panLeft(1.0f), 1145 _panRight(1.0f), 1146 _outputGain(1.0f), 1147 _encrypting(false), 1148 _decrypting(false), 1149 _playOutbandDtmfEvent(false), 1150 _playInbandDtmfEvent(false), 1151 _inbandTelephoneEventDetection(false), 1152 _outOfBandTelephoneEventDetecion(false), 1153 _extraPayloadType(0), 1154 _insertExtraRTPPacket(false), 1155 _extraMarkerBit(false), 1156 _lastLocalTimeStamp(0), 1157 _lastRemoteTimeStamp(0), 1158 _lastPayloadType(0), 1159 _includeAudioLevelIndication(false), 1160 _rtpPacketTimedOut(false), 1161 _rtpPacketTimeOutIsEnabled(false), 1162 _rtpTimeOutSeconds(0), 1163 _connectionObserver(false), 1164 _connectionObserverPtr(NULL), 1165 _countAliveDetections(0), 1166 _countDeadDetections(0), 1167 _outputSpeechType(AudioFrame::kNormalSpeech), 1168 _averageDelayMs(0), 1169 _previousSequenceNumber(0), 1170 _previousTimestamp(0), 1171 _recPacketDelayMs(20), 1172 _RxVadDetection(false), 1173 _rxApmIsEnabled(false), 1174 _rxAgcIsEnabled(false), 1175 _rxNsIsEnabled(false) 1176{ 1177 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 1178 "Channel::Channel() - ctor"); 1179 _inbandDtmfQueue.ResetDtmf(); 1180 _inbandDtmfGenerator.Init(); 1181 _outputAudioLevel.Clear(); 1182 1183 RtpRtcp::Configuration configuration; 1184 configuration.id = VoEModuleId(instanceId, channelId); 1185 configuration.audio = true; 1186 configuration.incoming_data = this; 1187 configuration.incoming_messages = this; 1188 configuration.outgoing_transport = this; 1189 configuration.rtcp_feedback = this; 1190 configuration.audio_messages = this; 1191 1192 _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); 1193 1194 // Create far end AudioProcessing Module 1195 _rxAudioProcessingModulePtr = AudioProcessing::Create( 1196 VoEModuleId(instanceId, channelId)); 1197} 1198 1199Channel::~Channel() 1200{ 1201 WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 1202 "Channel::~Channel() - dtor"); 1203 1204 if (_outputExternalMedia) 1205 { 1206 DeRegisterExternalMediaProcessing(kPlaybackPerChannel); 1207 } 1208 if (_inputExternalMedia) 1209 { 1210 DeRegisterExternalMediaProcessing(kRecordingPerChannel); 1211 } 1212 StopSend(); 1213#ifndef WEBRTC_EXTERNAL_TRANSPORT 1214 StopReceiving(); 1215 // De-register packet callback to ensure we're not in a callback when 1216 // deleting channel state, avoids race condition and deadlock. 1217 if (_socketTransportModule.InitializeReceiveSockets(NULL, 0, NULL, NULL, 0) 1218 != 0) 1219 { 1220 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1221 VoEId(_instanceId, _channelId), 1222 "~Channel() failed to de-register receive callback"); 1223 } 1224#endif 1225 StopPlayout(); 1226 1227 { 1228 CriticalSectionScoped cs(&_fileCritSect); 1229 if (_inputFilePlayerPtr) 1230 { 1231 _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1232 _inputFilePlayerPtr->StopPlayingFile(); 1233 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 1234 _inputFilePlayerPtr = NULL; 1235 } 1236 if (_outputFilePlayerPtr) 1237 { 1238 _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1239 _outputFilePlayerPtr->StopPlayingFile(); 1240 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1241 _outputFilePlayerPtr = NULL; 1242 } 1243 if (_outputFileRecorderPtr) 1244 { 1245 _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 1246 _outputFileRecorderPtr->StopRecording(); 1247 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 1248 _outputFileRecorderPtr = NULL; 1249 } 1250 } 1251 1252 // The order to safely shutdown modules in a channel is: 1253 // 1. De-register callbacks in modules 1254 // 2. De-register modules in process thread 1255 // 3. Destroy modules 1256 if (_audioCodingModule.RegisterTransportCallback(NULL) == -1) 1257 { 1258 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1259 VoEId(_instanceId,_channelId), 1260 "~Channel() failed to de-register transport callback" 1261 " (Audio coding module)"); 1262 } 1263 if (_audioCodingModule.RegisterVADCallback(NULL) == -1) 1264 { 1265 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1266 VoEId(_instanceId,_channelId), 1267 "~Channel() failed to de-register VAD callback" 1268 " (Audio coding module)"); 1269 } 1270#ifdef WEBRTC_DTMF_DETECTION 1271 if (_audioCodingModule.RegisterIncomingMessagesCallback(NULL) == -1) 1272 { 1273 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1274 VoEId(_instanceId,_channelId), 1275 "~Channel() failed to de-register incoming messages " 1276 "callback (Audio coding module)"); 1277 } 1278#endif 1279 // De-register modules in process thread 1280#ifndef WEBRTC_EXTERNAL_TRANSPORT 1281 if (_moduleProcessThreadPtr->DeRegisterModule(&_socketTransportModule) 1282 == -1) 1283 { 1284 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1285 VoEId(_instanceId,_channelId), 1286 "~Channel() failed to deregister socket module"); 1287 } 1288#endif 1289 if (_moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()) == -1) 1290 { 1291 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1292 VoEId(_instanceId,_channelId), 1293 "~Channel() failed to deregister RTP/RTCP module"); 1294 } 1295 1296 // Destroy modules 1297#ifndef WEBRTC_EXTERNAL_TRANSPORT 1298 UdpTransport::Destroy( 1299 &_socketTransportModule); 1300#endif 1301 AudioCodingModule::Destroy(&_audioCodingModule); 1302#ifdef WEBRTC_SRTP 1303 SrtpModule::DestroySrtpModule(&_srtpModule); 1304#endif 1305 if (_rxAudioProcessingModulePtr != NULL) 1306 { 1307 AudioProcessing::Destroy(_rxAudioProcessingModulePtr); // far end APM 1308 _rxAudioProcessingModulePtr = NULL; 1309 } 1310 1311 // End of modules shutdown 1312 1313 // Delete other objects 1314 RtpDump::DestroyRtpDump(&_rtpDumpIn); 1315 RtpDump::DestroyRtpDump(&_rtpDumpOut); 1316 delete [] _encryptionRTPBufferPtr; 1317 delete [] _decryptionRTPBufferPtr; 1318 delete [] _encryptionRTCPBufferPtr; 1319 delete [] _decryptionRTCPBufferPtr; 1320 delete &_callbackCritSect; 1321 delete &_fileCritSect; 1322} 1323 1324WebRtc_Word32 1325Channel::Init() 1326{ 1327 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1328 "Channel::Init()"); 1329 1330 // --- Initial sanity 1331 1332 if ((_engineStatisticsPtr == NULL) || 1333 (_moduleProcessThreadPtr == NULL)) 1334 { 1335 WEBRTC_TRACE(kTraceError, kTraceVoice, 1336 VoEId(_instanceId,_channelId), 1337 "Channel::Init() must call SetEngineInformation() first"); 1338 return -1; 1339 } 1340 1341 // --- Add modules to process thread (for periodic schedulation) 1342 1343 const bool processThreadFail = 1344 ((_moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()) != 0) || 1345#ifndef WEBRTC_EXTERNAL_TRANSPORT 1346 (_moduleProcessThreadPtr->RegisterModule( 1347 &_socketTransportModule) != 0)); 1348#else 1349 false); 1350#endif 1351 if (processThreadFail) 1352 { 1353 _engineStatisticsPtr->SetLastError( 1354 VE_CANNOT_INIT_CHANNEL, kTraceError, 1355 "Channel::Init() modules not registered"); 1356 return -1; 1357 } 1358 // --- ACM initialization 1359 1360 if ((_audioCodingModule.InitializeReceiver() == -1) || 1361#ifdef WEBRTC_CODEC_AVT 1362 // out-of-band Dtmf tones are played out by default 1363 (_audioCodingModule.SetDtmfPlayoutStatus(true) == -1) || 1364#endif 1365 (_audioCodingModule.InitializeSender() == -1)) 1366 { 1367 _engineStatisticsPtr->SetLastError( 1368 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1369 "Channel::Init() unable to initialize the ACM - 1"); 1370 return -1; 1371 } 1372 1373 // --- RTP/RTCP module initialization 1374 1375 // Ensure that RTCP is enabled by default for the created channel. 1376 // Note that, the module will keep generating RTCP until it is explicitly 1377 // disabled by the user. 1378 // After StopListen (when no sockets exists), RTCP packets will no longer 1379 // be transmitted since the Transport object will then be invalid. 1380 1381 const bool rtpRtcpFail = 1382 ((_rtpRtcpModule->SetTelephoneEventStatus(false, true, true) == -1) || 1383 // RTCP is enabled by default 1384 (_rtpRtcpModule->SetRTCPStatus(kRtcpCompound) == -1)); 1385 if (rtpRtcpFail) 1386 { 1387 _engineStatisticsPtr->SetLastError( 1388 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1389 "Channel::Init() RTP/RTCP module not initialized"); 1390 return -1; 1391 } 1392 1393 // --- Register all permanent callbacks 1394 const bool fail = 1395 (_audioCodingModule.RegisterTransportCallback(this) == -1) || 1396 (_audioCodingModule.RegisterVADCallback(this) == -1); 1397 1398 if (fail) 1399 { 1400 _engineStatisticsPtr->SetLastError( 1401 VE_CANNOT_INIT_CHANNEL, kTraceError, 1402 "Channel::Init() callbacks not registered"); 1403 return -1; 1404 } 1405 1406 // --- Register all supported codecs to the receiving side of the 1407 // RTP/RTCP module 1408 1409 CodecInst codec; 1410 const WebRtc_UWord8 nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 1411 1412 for (int idx = 0; idx < nSupportedCodecs; idx++) 1413 { 1414 // Open up the RTP/RTCP receiver for all supported codecs 1415 if ((_audioCodingModule.Codec(idx, codec) == -1) || 1416 (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 1417 { 1418 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1419 VoEId(_instanceId,_channelId), 1420 "Channel::Init() unable to register %s (%d/%d/%d/%d) " 1421 "to RTP/RTCP receiver", 1422 codec.plname, codec.pltype, codec.plfreq, 1423 codec.channels, codec.rate); 1424 } 1425 else 1426 { 1427 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1428 VoEId(_instanceId,_channelId), 1429 "Channel::Init() %s (%d/%d/%d/%d) has been added to " 1430 "the RTP/RTCP receiver", 1431 codec.plname, codec.pltype, codec.plfreq, 1432 codec.channels, codec.rate); 1433 } 1434 1435 // Ensure that PCMU is used as default codec on the sending side 1436 if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) 1437 { 1438 SetSendCodec(codec); 1439 } 1440 1441 // Register default PT for outband 'telephone-event' 1442 if (!STR_CASE_CMP(codec.plname, "telephone-event")) 1443 { 1444 if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || 1445 (_audioCodingModule.RegisterReceiveCodec(codec) == -1)) 1446 { 1447 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1448 VoEId(_instanceId,_channelId), 1449 "Channel::Init() failed to register outband " 1450 "'telephone-event' (%d/%d) correctly", 1451 codec.pltype, codec.plfreq); 1452 } 1453 } 1454 1455 if (!STR_CASE_CMP(codec.plname, "CN")) 1456 { 1457 if ((_audioCodingModule.RegisterSendCodec(codec) == -1) || 1458 (_audioCodingModule.RegisterReceiveCodec(codec) == -1) || 1459 (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) 1460 { 1461 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1462 VoEId(_instanceId,_channelId), 1463 "Channel::Init() failed to register CN (%d/%d) " 1464 "correctly - 1", 1465 codec.pltype, codec.plfreq); 1466 } 1467 } 1468#ifdef WEBRTC_CODEC_RED 1469 // Register RED to the receiving side of the ACM. 1470 // We will not receive an OnInitializeDecoder() callback for RED. 1471 if (!STR_CASE_CMP(codec.plname, "RED")) 1472 { 1473 if (_audioCodingModule.RegisterReceiveCodec(codec) == -1) 1474 { 1475 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1476 VoEId(_instanceId,_channelId), 1477 "Channel::Init() failed to register RED (%d/%d) " 1478 "correctly", 1479 codec.pltype, codec.plfreq); 1480 } 1481 } 1482#endif 1483 } 1484#ifndef WEBRTC_EXTERNAL_TRANSPORT 1485 // Ensure that the WebRtcSocketTransport implementation is used as 1486 // Transport on the sending side 1487 { 1488 // A lock is needed here since users can call 1489 // RegisterExternalTransport() at the same time. 1490 CriticalSectionScoped cs(&_callbackCritSect); 1491 _transportPtr = &_socketTransportModule; 1492 } 1493#endif 1494 1495 // Initialize the far end AP module 1496 // Using 8 kHz as initial Fs, the same as in transmission. Might be 1497 // changed at the first receiving audio. 1498 if (_rxAudioProcessingModulePtr == NULL) 1499 { 1500 _engineStatisticsPtr->SetLastError( 1501 VE_NO_MEMORY, kTraceCritical, 1502 "Channel::Init() failed to create the far-end AudioProcessing" 1503 " module"); 1504 return -1; 1505 } 1506 1507 if (_rxAudioProcessingModulePtr->set_sample_rate_hz(8000)) 1508 { 1509 _engineStatisticsPtr->SetLastError( 1510 VE_APM_ERROR, kTraceWarning, 1511 "Channel::Init() failed to set the sample rate to 8K for" 1512 " far-end AP module"); 1513 } 1514 1515 if (_rxAudioProcessingModulePtr->set_num_channels(1, 1) != 0) 1516 { 1517 _engineStatisticsPtr->SetLastError( 1518 VE_SOUNDCARD_ERROR, kTraceWarning, 1519 "Init() failed to set channels for the primary audio stream"); 1520 } 1521 1522 if (_rxAudioProcessingModulePtr->high_pass_filter()->Enable( 1523 WEBRTC_VOICE_ENGINE_RX_HP_DEFAULT_STATE) != 0) 1524 { 1525 _engineStatisticsPtr->SetLastError( 1526 VE_APM_ERROR, kTraceWarning, 1527 "Channel::Init() failed to set the high-pass filter for" 1528 " far-end AP module"); 1529 } 1530 1531 if (_rxAudioProcessingModulePtr->noise_suppression()->set_level( 1532 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE) != 0) 1533 { 1534 _engineStatisticsPtr->SetLastError( 1535 VE_APM_ERROR, kTraceWarning, 1536 "Init() failed to set noise reduction level for far-end" 1537 " AP module"); 1538 } 1539 if (_rxAudioProcessingModulePtr->noise_suppression()->Enable( 1540 WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_STATE) != 0) 1541 { 1542 _engineStatisticsPtr->SetLastError( 1543 VE_APM_ERROR, kTraceWarning, 1544 "Init() failed to set noise reduction state for far-end" 1545 " AP module"); 1546 } 1547 1548 if (_rxAudioProcessingModulePtr->gain_control()->set_mode( 1549 (GainControl::Mode)WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_MODE) != 0) 1550 { 1551 _engineStatisticsPtr->SetLastError( 1552 VE_APM_ERROR, kTraceWarning, 1553 "Init() failed to set AGC mode for far-end AP module"); 1554 } 1555 if (_rxAudioProcessingModulePtr->gain_control()->Enable( 1556 WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_STATE) != 0) 1557 { 1558 _engineStatisticsPtr->SetLastError( 1559 VE_APM_ERROR, kTraceWarning, 1560 "Init() failed to set AGC state for far-end AP module"); 1561 } 1562 1563 return 0; 1564} 1565 1566WebRtc_Word32 1567Channel::SetEngineInformation(Statistics& engineStatistics, 1568 OutputMixer& outputMixer, 1569 voe::TransmitMixer& transmitMixer, 1570 ProcessThread& moduleProcessThread, 1571 AudioDeviceModule& audioDeviceModule, 1572 VoiceEngineObserver* voiceEngineObserver, 1573 CriticalSectionWrapper* callbackCritSect) 1574{ 1575 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1576 "Channel::SetEngineInformation()"); 1577 _engineStatisticsPtr = &engineStatistics; 1578 _outputMixerPtr = &outputMixer; 1579 _transmitMixerPtr = &transmitMixer, 1580 _moduleProcessThreadPtr = &moduleProcessThread; 1581 _audioDeviceModulePtr = &audioDeviceModule; 1582 _voiceEngineObserverPtr = voiceEngineObserver; 1583 _callbackCritSectPtr = callbackCritSect; 1584 return 0; 1585} 1586 1587WebRtc_Word32 1588Channel::UpdateLocalTimeStamp() 1589{ 1590 1591 _timeStamp += _audioFrame.samples_per_channel_; 1592 return 0; 1593} 1594 1595WebRtc_Word32 1596Channel::StartPlayout() 1597{ 1598 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1599 "Channel::StartPlayout()"); 1600 if (_playing) 1601 { 1602 return 0; 1603 } 1604 // Add participant as candidates for mixing. 1605 if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) 1606 { 1607 _engineStatisticsPtr->SetLastError( 1608 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1609 "StartPlayout() failed to add participant to mixer"); 1610 return -1; 1611 } 1612 1613 _playing = true; 1614 1615 if (RegisterFilePlayingToMixer() != 0) 1616 return -1; 1617 1618 return 0; 1619} 1620 1621WebRtc_Word32 1622Channel::StopPlayout() 1623{ 1624 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1625 "Channel::StopPlayout()"); 1626 if (!_playing) 1627 { 1628 return 0; 1629 } 1630 // Remove participant as candidates for mixing 1631 if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) 1632 { 1633 _engineStatisticsPtr->SetLastError( 1634 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1635 "StartPlayout() failed to remove participant from mixer"); 1636 return -1; 1637 } 1638 1639 _playing = false; 1640 _outputAudioLevel.Clear(); 1641 1642 return 0; 1643} 1644 1645WebRtc_Word32 1646Channel::StartSend() 1647{ 1648 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1649 "Channel::StartSend()"); 1650 { 1651 // A lock is needed because |_sending| can be accessed or modified by 1652 // another thread at the same time. 1653 CriticalSectionScoped cs(&_callbackCritSect); 1654 1655 if (_sending) 1656 { 1657 return 0; 1658 } 1659 _sending = true; 1660 } 1661 1662 if (_rtpRtcpModule->SetSendingStatus(true) != 0) 1663 { 1664 _engineStatisticsPtr->SetLastError( 1665 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1666 "StartSend() RTP/RTCP failed to start sending"); 1667 CriticalSectionScoped cs(&_callbackCritSect); 1668 _sending = false; 1669 return -1; 1670 } 1671 1672 return 0; 1673} 1674 1675WebRtc_Word32 1676Channel::StopSend() 1677{ 1678 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1679 "Channel::StopSend()"); 1680 { 1681 // A lock is needed because |_sending| can be accessed or modified by 1682 // another thread at the same time. 1683 CriticalSectionScoped cs(&_callbackCritSect); 1684 1685 if (!_sending) 1686 { 1687 return 0; 1688 } 1689 _sending = false; 1690 } 1691 1692 // Reset sending SSRC and sequence number and triggers direct transmission 1693 // of RTCP BYE 1694 if (_rtpRtcpModule->SetSendingStatus(false) == -1 || 1695 _rtpRtcpModule->ResetSendDataCountersRTP() == -1) 1696 { 1697 _engineStatisticsPtr->SetLastError( 1698 VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1699 "StartSend() RTP/RTCP failed to stop sending"); 1700 } 1701 1702 return 0; 1703} 1704 1705WebRtc_Word32 1706Channel::StartReceiving() 1707{ 1708 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1709 "Channel::StartReceiving()"); 1710 if (_receiving) 1711 { 1712 return 0; 1713 } 1714 // If external transport is used, we will only initialize/set the variables 1715 // after this section, since we are not using the WebRtc transport but 1716 // still need to keep track of e.g. if we are receiving. 1717#ifndef WEBRTC_EXTERNAL_TRANSPORT 1718 if (!_externalTransport) 1719 { 1720 if (!_socketTransportModule.ReceiveSocketsInitialized()) 1721 { 1722 _engineStatisticsPtr->SetLastError( 1723 VE_SOCKETS_NOT_INITED, kTraceError, 1724 "StartReceive() must set local receiver first"); 1725 return -1; 1726 } 1727 if (_socketTransportModule.StartReceiving(KNumberOfSocketBuffers) != 0) 1728 { 1729 _engineStatisticsPtr->SetLastError( 1730 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 1731 "StartReceiving() failed to start receiving"); 1732 return -1; 1733 } 1734 } 1735#endif 1736 _receiving = true; 1737 _numberOfDiscardedPackets = 0; 1738 return 0; 1739} 1740 1741WebRtc_Word32 1742Channel::StopReceiving() 1743{ 1744 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1745 "Channel::StopReceiving()"); 1746 if (!_receiving) 1747 { 1748 return 0; 1749 } 1750 1751#ifndef WEBRTC_EXTERNAL_TRANSPORT 1752 if (!_externalTransport && 1753 _socketTransportModule.ReceiveSocketsInitialized()) 1754 { 1755 if (_socketTransportModule.StopReceiving() != 0) 1756 { 1757 _engineStatisticsPtr->SetLastError( 1758 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 1759 "StopReceiving() failed to stop receiving."); 1760 return -1; 1761 } 1762 } 1763#endif 1764 bool dtmfDetection = _rtpRtcpModule->TelephoneEvent(); 1765 // Recover DTMF detection status. 1766 WebRtc_Word32 ret = _rtpRtcpModule->SetTelephoneEventStatus(dtmfDetection, 1767 true, true); 1768 if (ret != 0) { 1769 _engineStatisticsPtr->SetLastError( 1770 VE_INVALID_OPERATION, kTraceWarning, 1771 "StopReceiving() failed to restore telephone-event status."); 1772 } 1773 RegisterReceiveCodecsToRTPModule(); 1774 _receiving = false; 1775 return 0; 1776} 1777 1778#ifndef WEBRTC_EXTERNAL_TRANSPORT 1779WebRtc_Word32 1780Channel::SetLocalReceiver(const WebRtc_UWord16 rtpPort, 1781 const WebRtc_UWord16 rtcpPort, 1782 const char ipAddr[64], 1783 const char multicastIpAddr[64]) 1784{ 1785 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1786 "Channel::SetLocalReceiver()"); 1787 1788 if (_externalTransport) 1789 { 1790 _engineStatisticsPtr->SetLastError( 1791 VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1792 "SetLocalReceiver() conflict with external transport"); 1793 return -1; 1794 } 1795 1796 if (_sending) 1797 { 1798 _engineStatisticsPtr->SetLastError( 1799 VE_ALREADY_SENDING, kTraceError, 1800 "SetLocalReceiver() already sending"); 1801 return -1; 1802 } 1803 if (_receiving) 1804 { 1805 _engineStatisticsPtr->SetLastError( 1806 VE_ALREADY_LISTENING, kTraceError, 1807 "SetLocalReceiver() already receiving"); 1808 return -1; 1809 } 1810 1811 if (_socketTransportModule.InitializeReceiveSockets(this, 1812 rtpPort, 1813 ipAddr, 1814 multicastIpAddr, 1815 rtcpPort) != 0) 1816 { 1817 UdpTransport::ErrorCode lastSockError( 1818 _socketTransportModule.LastError()); 1819 switch (lastSockError) 1820 { 1821 case UdpTransport::kIpAddressInvalid: 1822 _engineStatisticsPtr->SetLastError( 1823 VE_INVALID_IP_ADDRESS, kTraceError, 1824 "SetLocalReceiver() invalid IP address"); 1825 break; 1826 case UdpTransport::kSocketInvalid: 1827 _engineStatisticsPtr->SetLastError( 1828 VE_SOCKET_ERROR, kTraceError, 1829 "SetLocalReceiver() invalid socket"); 1830 break; 1831 case UdpTransport::kPortInvalid: 1832 _engineStatisticsPtr->SetLastError( 1833 VE_INVALID_PORT_NMBR, kTraceError, 1834 "SetLocalReceiver() invalid port"); 1835 break; 1836 case UdpTransport::kFailedToBindPort: 1837 _engineStatisticsPtr->SetLastError( 1838 VE_BINDING_SOCKET_TO_LOCAL_ADDRESS_FAILED, kTraceError, 1839 "SetLocalReceiver() binding failed"); 1840 break; 1841 default: 1842 _engineStatisticsPtr->SetLastError( 1843 VE_SOCKET_ERROR, kTraceError, 1844 "SetLocalReceiver() undefined socket error"); 1845 break; 1846 } 1847 return -1; 1848 } 1849 return 0; 1850} 1851#endif 1852 1853#ifndef WEBRTC_EXTERNAL_TRANSPORT 1854WebRtc_Word32 1855Channel::GetLocalReceiver(int& port, int& RTCPport, char ipAddr[64]) 1856{ 1857 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1858 "Channel::GetLocalReceiver()"); 1859 1860 if (_externalTransport) 1861 { 1862 _engineStatisticsPtr->SetLastError( 1863 VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1864 "SetLocalReceiver() conflict with external transport"); 1865 return -1; 1866 } 1867 1868 char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 1869 WebRtc_UWord16 rtpPort(0); 1870 WebRtc_UWord16 rtcpPort(0); 1871 char multicastIpAddr[UdpTransport::kIpAddressVersion6Length] = {0}; 1872 1873 // Acquire socket information from the socket module 1874 if (_socketTransportModule.ReceiveSocketInformation(ipAddrTmp, 1875 rtpPort, 1876 rtcpPort, 1877 multicastIpAddr) != 0) 1878 { 1879 _engineStatisticsPtr->SetLastError( 1880 VE_CANNOT_GET_SOCKET_INFO, kTraceError, 1881 "GetLocalReceiver() unable to retrieve socket information"); 1882 return -1; 1883 } 1884 1885 // Deliver valid results to the user 1886 port = static_cast<int> (rtpPort); 1887 RTCPport = static_cast<int> (rtcpPort); 1888 if (ipAddr != NULL) 1889 { 1890 strcpy(ipAddr, ipAddrTmp); 1891 } 1892 return 0; 1893} 1894#endif 1895 1896#ifndef WEBRTC_EXTERNAL_TRANSPORT 1897WebRtc_Word32 1898Channel::SetSendDestination(const WebRtc_UWord16 rtpPort, 1899 const char ipAddr[64], 1900 const int sourcePort, 1901 const WebRtc_UWord16 rtcpPort) 1902{ 1903 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1904 "Channel::SetSendDestination()"); 1905 1906 if (_externalTransport) 1907 { 1908 _engineStatisticsPtr->SetLastError( 1909 VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1910 "SetSendDestination() conflict with external transport"); 1911 return -1; 1912 } 1913 1914 // Initialize ports and IP address for the remote (destination) side. 1915 // By default, the sockets used for receiving are used for transmission as 1916 // well, hence the source ports for outgoing packets are the same as the 1917 // receiving ports specified in SetLocalReceiver. 1918 // If an extra send socket has been created, it will be utilized until a 1919 // new source port is specified or until the channel has been deleted and 1920 // recreated. If no socket exists, sockets will be created when the first 1921 // RTP and RTCP packets shall be transmitted (see e.g. 1922 // UdpTransportImpl::SendPacket()). 1923 // 1924 // NOTE: this function does not require that sockets exists; all it does is 1925 // to build send structures to be used with the sockets when they exist. 1926 // It is therefore possible to call this method before SetLocalReceiver. 1927 // However, sockets must exist if a multi-cast address is given as input. 1928 1929 // Build send structures and enable QoS (if enabled and supported) 1930 if (_socketTransportModule.InitializeSendSockets( 1931 ipAddr, rtpPort, rtcpPort) != UdpTransport::kNoSocketError) 1932 { 1933 UdpTransport::ErrorCode lastSockError( 1934 _socketTransportModule.LastError()); 1935 switch (lastSockError) 1936 { 1937 case UdpTransport::kIpAddressInvalid: 1938 _engineStatisticsPtr->SetLastError( 1939 VE_INVALID_IP_ADDRESS, kTraceError, 1940 "SetSendDestination() invalid IP address 1"); 1941 break; 1942 case UdpTransport::kSocketInvalid: 1943 _engineStatisticsPtr->SetLastError( 1944 VE_SOCKET_ERROR, kTraceError, 1945 "SetSendDestination() invalid socket 1"); 1946 break; 1947 case UdpTransport::kQosError: 1948 _engineStatisticsPtr->SetLastError( 1949 VE_GQOS_ERROR, kTraceError, 1950 "SetSendDestination() failed to set QoS"); 1951 break; 1952 case UdpTransport::kMulticastAddressInvalid: 1953 _engineStatisticsPtr->SetLastError( 1954 VE_INVALID_MULTICAST_ADDRESS, kTraceError, 1955 "SetSendDestination() invalid multicast address"); 1956 break; 1957 default: 1958 _engineStatisticsPtr->SetLastError( 1959 VE_SOCKET_ERROR, kTraceError, 1960 "SetSendDestination() undefined socket error 1"); 1961 break; 1962 } 1963 return -1; 1964 } 1965 1966 // Check if the user has specified a non-default source port different from 1967 // the local receive port. 1968 // If so, an extra local socket will be created unless the source port is 1969 // not unique. 1970 if (sourcePort != kVoEDefault) 1971 { 1972 WebRtc_UWord16 receiverRtpPort(0); 1973 WebRtc_UWord16 rtcpNA(0); 1974 if (_socketTransportModule.ReceiveSocketInformation(NULL, 1975 receiverRtpPort, 1976 rtcpNA, 1977 NULL) != 0) 1978 { 1979 _engineStatisticsPtr->SetLastError( 1980 VE_CANNOT_GET_SOCKET_INFO, kTraceError, 1981 "SetSendDestination() failed to retrieve socket information"); 1982 return -1; 1983 } 1984 1985 WebRtc_UWord16 sourcePortUW16 = 1986 static_cast<WebRtc_UWord16> (sourcePort); 1987 1988 // An extra socket will only be created if the specified source port 1989 // differs from the local receive port. 1990 if (sourcePortUW16 != receiverRtpPort) 1991 { 1992 // Initialize extra local socket to get a different source port 1993 // than the local 1994 // receiver port. Always use default source for RTCP. 1995 // Note that, this calls UdpTransport::CloseSendSockets(). 1996 if (_socketTransportModule.InitializeSourcePorts( 1997 sourcePortUW16, 1998 sourcePortUW16+1) != 0) 1999 { 2000 UdpTransport::ErrorCode lastSockError( 2001 _socketTransportModule.LastError()); 2002 switch (lastSockError) 2003 { 2004 case UdpTransport::kIpAddressInvalid: 2005 _engineStatisticsPtr->SetLastError( 2006 VE_INVALID_IP_ADDRESS, kTraceError, 2007 "SetSendDestination() invalid IP address 2"); 2008 break; 2009 case UdpTransport::kSocketInvalid: 2010 _engineStatisticsPtr->SetLastError( 2011 VE_SOCKET_ERROR, kTraceError, 2012 "SetSendDestination() invalid socket 2"); 2013 break; 2014 default: 2015 _engineStatisticsPtr->SetLastError( 2016 VE_SOCKET_ERROR, kTraceError, 2017 "SetSendDestination() undefined socket error 2"); 2018 break; 2019 } 2020 return -1; 2021 } 2022 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 2023 VoEId(_instanceId,_channelId), 2024 "SetSendDestination() extra local socket is created" 2025 " to facilitate unique source port"); 2026 } 2027 else 2028 { 2029 WEBRTC_TRACE(kTraceInfo, kTraceVoice, 2030 VoEId(_instanceId,_channelId), 2031 "SetSendDestination() sourcePort equals the local" 2032 " receive port => no extra socket is created"); 2033 } 2034 } 2035 2036 return 0; 2037} 2038#endif 2039 2040#ifndef WEBRTC_EXTERNAL_TRANSPORT 2041WebRtc_Word32 2042Channel::GetSendDestination(int& port, 2043 char ipAddr[64], 2044 int& sourcePort, 2045 int& RTCPport) 2046{ 2047 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2048 "Channel::GetSendDestination()"); 2049 2050 if (_externalTransport) 2051 { 2052 _engineStatisticsPtr->SetLastError( 2053 VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 2054 "GetSendDestination() conflict with external transport"); 2055 return -1; 2056 } 2057 2058 char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 2059 WebRtc_UWord16 rtpPort(0); 2060 WebRtc_UWord16 rtcpPort(0); 2061 WebRtc_UWord16 rtpSourcePort(0); 2062 WebRtc_UWord16 rtcpSourcePort(0); 2063 2064 // Acquire sending socket information from the socket module 2065 _socketTransportModule.SendSocketInformation(ipAddrTmp, rtpPort, rtcpPort); 2066 _socketTransportModule.SourcePorts(rtpSourcePort, rtcpSourcePort); 2067 2068 // Deliver valid results to the user 2069 port = static_cast<int> (rtpPort); 2070 RTCPport = static_cast<int> (rtcpPort); 2071 sourcePort = static_cast<int> (rtpSourcePort); 2072 if (ipAddr != NULL) 2073 { 2074 strcpy(ipAddr, ipAddrTmp); 2075 } 2076 2077 return 0; 2078} 2079#endif 2080 2081 2082WebRtc_Word32 2083Channel::SetNetEQPlayoutMode(NetEqModes mode) 2084{ 2085 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2086 "Channel::SetNetEQPlayoutMode()"); 2087 AudioPlayoutMode playoutMode(voice); 2088 switch (mode) 2089 { 2090 case kNetEqDefault: 2091 playoutMode = voice; 2092 break; 2093 case kNetEqStreaming: 2094 playoutMode = streaming; 2095 break; 2096 case kNetEqFax: 2097 playoutMode = fax; 2098 break; 2099 } 2100 if (_audioCodingModule.SetPlayoutMode(playoutMode) != 0) 2101 { 2102 _engineStatisticsPtr->SetLastError( 2103 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2104 "SetNetEQPlayoutMode() failed to set playout mode"); 2105 return -1; 2106 } 2107 return 0; 2108} 2109 2110WebRtc_Word32 2111Channel::GetNetEQPlayoutMode(NetEqModes& mode) 2112{ 2113 const AudioPlayoutMode playoutMode = _audioCodingModule.PlayoutMode(); 2114 switch (playoutMode) 2115 { 2116 case voice: 2117 mode = kNetEqDefault; 2118 break; 2119 case streaming: 2120 mode = kNetEqStreaming; 2121 break; 2122 case fax: 2123 mode = kNetEqFax; 2124 break; 2125 } 2126 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2127 VoEId(_instanceId,_channelId), 2128 "Channel::GetNetEQPlayoutMode() => mode=%u", mode); 2129 return 0; 2130} 2131 2132WebRtc_Word32 2133Channel::SetNetEQBGNMode(NetEqBgnModes mode) 2134{ 2135 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2136 "Channel::SetNetEQPlayoutMode()"); 2137 ACMBackgroundNoiseMode noiseMode(On); 2138 switch (mode) 2139 { 2140 case kBgnOn: 2141 noiseMode = On; 2142 break; 2143 case kBgnFade: 2144 noiseMode = Fade; 2145 break; 2146 case kBgnOff: 2147 noiseMode = Off; 2148 break; 2149 } 2150 if (_audioCodingModule.SetBackgroundNoiseMode(noiseMode) != 0) 2151 { 2152 _engineStatisticsPtr->SetLastError( 2153 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2154 "SetBackgroundNoiseMode() failed to set noise mode"); 2155 return -1; 2156 } 2157 return 0; 2158} 2159 2160WebRtc_Word32 2161Channel::SetOnHoldStatus(bool enable, OnHoldModes mode) 2162{ 2163 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2164 "Channel::SetOnHoldStatus()"); 2165 if (mode == kHoldSendAndPlay) 2166 { 2167 _outputIsOnHold = enable; 2168 _inputIsOnHold = enable; 2169 } 2170 else if (mode == kHoldPlayOnly) 2171 { 2172 _outputIsOnHold = enable; 2173 } 2174 if (mode == kHoldSendOnly) 2175 { 2176 _inputIsOnHold = enable; 2177 } 2178 return 0; 2179} 2180 2181WebRtc_Word32 2182Channel::GetOnHoldStatus(bool& enabled, OnHoldModes& mode) 2183{ 2184 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2185 "Channel::GetOnHoldStatus()"); 2186 enabled = (_outputIsOnHold || _inputIsOnHold); 2187 if (_outputIsOnHold && _inputIsOnHold) 2188 { 2189 mode = kHoldSendAndPlay; 2190 } 2191 else if (_outputIsOnHold && !_inputIsOnHold) 2192 { 2193 mode = kHoldPlayOnly; 2194 } 2195 else if (!_outputIsOnHold && _inputIsOnHold) 2196 { 2197 mode = kHoldSendOnly; 2198 } 2199 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2200 "Channel::GetOnHoldStatus() => enabled=%d, mode=%d", 2201 enabled, mode); 2202 return 0; 2203} 2204 2205WebRtc_Word32 2206Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 2207{ 2208 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2209 "Channel::RegisterVoiceEngineObserver()"); 2210 CriticalSectionScoped cs(&_callbackCritSect); 2211 2212 if (_voiceEngineObserverPtr) 2213 { 2214 _engineStatisticsPtr->SetLastError( 2215 VE_INVALID_OPERATION, kTraceError, 2216 "RegisterVoiceEngineObserver() observer already enabled"); 2217 return -1; 2218 } 2219 _voiceEngineObserverPtr = &observer; 2220 return 0; 2221} 2222 2223WebRtc_Word32 2224Channel::DeRegisterVoiceEngineObserver() 2225{ 2226 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2227 "Channel::DeRegisterVoiceEngineObserver()"); 2228 CriticalSectionScoped cs(&_callbackCritSect); 2229 2230 if (!_voiceEngineObserverPtr) 2231 { 2232 _engineStatisticsPtr->SetLastError( 2233 VE_INVALID_OPERATION, kTraceWarning, 2234 "DeRegisterVoiceEngineObserver() observer already disabled"); 2235 return 0; 2236 } 2237 _voiceEngineObserverPtr = NULL; 2238 return 0; 2239} 2240 2241WebRtc_Word32 2242Channel::GetNetEQBGNMode(NetEqBgnModes& mode) 2243{ 2244 ACMBackgroundNoiseMode noiseMode(On); 2245 _audioCodingModule.BackgroundNoiseMode(noiseMode); 2246 switch (noiseMode) 2247 { 2248 case On: 2249 mode = kBgnOn; 2250 break; 2251 case Fade: 2252 mode = kBgnFade; 2253 break; 2254 case Off: 2255 mode = kBgnOff; 2256 break; 2257 } 2258 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2259 "Channel::GetNetEQBGNMode() => mode=%u", mode); 2260 return 0; 2261} 2262 2263WebRtc_Word32 2264Channel::GetSendCodec(CodecInst& codec) 2265{ 2266 return (_audioCodingModule.SendCodec(codec)); 2267} 2268 2269WebRtc_Word32 2270Channel::GetRecCodec(CodecInst& codec) 2271{ 2272 return (_audioCodingModule.ReceiveCodec(codec)); 2273} 2274 2275WebRtc_Word32 2276Channel::SetSendCodec(const CodecInst& codec) 2277{ 2278 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2279 "Channel::SetSendCodec()"); 2280 2281 if (_audioCodingModule.RegisterSendCodec(codec) != 0) 2282 { 2283 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2284 "SetSendCodec() failed to register codec to ACM"); 2285 return -1; 2286 } 2287 2288 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2289 { 2290 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 2291 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2292 { 2293 WEBRTC_TRACE( 2294 kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2295 "SetSendCodec() failed to register codec to" 2296 " RTP/RTCP module"); 2297 return -1; 2298 } 2299 } 2300 2301 if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) 2302 { 2303 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2304 "SetSendCodec() failed to set audio packet size"); 2305 return -1; 2306 } 2307 2308 return 0; 2309} 2310 2311WebRtc_Word32 2312Channel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) 2313{ 2314 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2315 "Channel::SetVADStatus(mode=%d)", mode); 2316 // To disable VAD, DTX must be disabled too 2317 disableDTX = ((enableVAD == false) ? true : disableDTX); 2318 if (_audioCodingModule.SetVAD(!disableDTX, enableVAD, mode) != 0) 2319 { 2320 _engineStatisticsPtr->SetLastError( 2321 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2322 "SetVADStatus() failed to set VAD"); 2323 return -1; 2324 } 2325 return 0; 2326} 2327 2328WebRtc_Word32 2329Channel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) 2330{ 2331 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2332 "Channel::GetVADStatus"); 2333 if (_audioCodingModule.VAD(disabledDTX, enabledVAD, mode) != 0) 2334 { 2335 _engineStatisticsPtr->SetLastError( 2336 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2337 "GetVADStatus() failed to get VAD status"); 2338 return -1; 2339 } 2340 disabledDTX = !disabledDTX; 2341 return 0; 2342} 2343 2344WebRtc_Word32 2345Channel::SetRecPayloadType(const CodecInst& codec) 2346{ 2347 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2348 "Channel::SetRecPayloadType()"); 2349 2350 if (_playing) 2351 { 2352 _engineStatisticsPtr->SetLastError( 2353 VE_ALREADY_PLAYING, kTraceError, 2354 "SetRecPayloadType() unable to set PT while playing"); 2355 return -1; 2356 } 2357 if (_receiving) 2358 { 2359 _engineStatisticsPtr->SetLastError( 2360 VE_ALREADY_LISTENING, kTraceError, 2361 "SetRecPayloadType() unable to set PT while listening"); 2362 return -1; 2363 } 2364 2365 if (codec.pltype == -1) 2366 { 2367 // De-register the selected codec (RTP/RTCP module and ACM) 2368 2369 WebRtc_Word8 pltype(-1); 2370 CodecInst rxCodec = codec; 2371 2372 // Get payload type for the given codec 2373 _rtpRtcpModule->ReceivePayloadType(rxCodec, &pltype); 2374 rxCodec.pltype = pltype; 2375 2376 if (_rtpRtcpModule->DeRegisterReceivePayload(pltype) != 0) 2377 { 2378 _engineStatisticsPtr->SetLastError( 2379 VE_RTP_RTCP_MODULE_ERROR, 2380 kTraceError, 2381 "SetRecPayloadType() RTP/RTCP-module deregistration " 2382 "failed"); 2383 return -1; 2384 } 2385 if (_audioCodingModule.UnregisterReceiveCodec(rxCodec.pltype) != 0) 2386 { 2387 _engineStatisticsPtr->SetLastError( 2388 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2389 "SetRecPayloadType() ACM deregistration failed - 1"); 2390 return -1; 2391 } 2392 return 0; 2393 } 2394 2395 if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 2396 { 2397 // First attempt to register failed => de-register and try again 2398 _rtpRtcpModule->DeRegisterReceivePayload(codec.pltype); 2399 if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 2400 { 2401 _engineStatisticsPtr->SetLastError( 2402 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2403 "SetRecPayloadType() RTP/RTCP-module registration failed"); 2404 return -1; 2405 } 2406 } 2407 if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 2408 { 2409 _audioCodingModule.UnregisterReceiveCodec(codec.pltype); 2410 if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 2411 { 2412 _engineStatisticsPtr->SetLastError( 2413 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2414 "SetRecPayloadType() ACM registration failed - 1"); 2415 return -1; 2416 } 2417 } 2418 return 0; 2419} 2420 2421WebRtc_Word32 2422Channel::GetRecPayloadType(CodecInst& codec) 2423{ 2424 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2425 "Channel::GetRecPayloadType()"); 2426 WebRtc_Word8 payloadType(-1); 2427 if (_rtpRtcpModule->ReceivePayloadType(codec, &payloadType) != 0) 2428 { 2429 _engineStatisticsPtr->SetLastError( 2430 VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 2431 "GetRecPayloadType() failed to retrieve RX payload type"); 2432 return -1; 2433 } 2434 codec.pltype = payloadType; 2435 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2436 "Channel::GetRecPayloadType() => pltype=%u", codec.pltype); 2437 return 0; 2438} 2439 2440WebRtc_Word32 2441Channel::SetAMREncFormat(AmrMode mode) 2442{ 2443 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2444 "Channel::SetAMREncFormat()"); 2445 2446 // ACM doesn't support AMR 2447 return -1; 2448} 2449 2450WebRtc_Word32 2451Channel::SetAMRDecFormat(AmrMode mode) 2452{ 2453 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2454 "Channel::SetAMRDecFormat()"); 2455 2456 // ACM doesn't support AMR 2457 return -1; 2458} 2459 2460WebRtc_Word32 2461Channel::SetAMRWbEncFormat(AmrMode mode) 2462{ 2463 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2464 "Channel::SetAMRWbEncFormat()"); 2465 2466 // ACM doesn't support AMR 2467 return -1; 2468 2469} 2470 2471WebRtc_Word32 2472Channel::SetAMRWbDecFormat(AmrMode mode) 2473{ 2474 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2475 "Channel::SetAMRWbDecFormat()"); 2476 2477 // ACM doesn't support AMR 2478 return -1; 2479} 2480 2481WebRtc_Word32 2482Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) 2483{ 2484 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2485 "Channel::SetSendCNPayloadType()"); 2486 2487 CodecInst codec; 2488 WebRtc_Word32 samplingFreqHz(-1); 2489 const int kMono = 1; 2490 if (frequency == kFreq32000Hz) 2491 samplingFreqHz = 32000; 2492 else if (frequency == kFreq16000Hz) 2493 samplingFreqHz = 16000; 2494 2495 if (_audioCodingModule.Codec("CN", codec, samplingFreqHz, kMono) == -1) 2496 { 2497 _engineStatisticsPtr->SetLastError( 2498 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2499 "SetSendCNPayloadType() failed to retrieve default CN codec " 2500 "settings"); 2501 return -1; 2502 } 2503 2504 // Modify the payload type (must be set to dynamic range) 2505 codec.pltype = type; 2506 2507 if (_audioCodingModule.RegisterSendCodec(codec) != 0) 2508 { 2509 _engineStatisticsPtr->SetLastError( 2510 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2511 "SetSendCNPayloadType() failed to register CN to ACM"); 2512 return -1; 2513 } 2514 2515 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2516 { 2517 _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 2518 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2519 { 2520 _engineStatisticsPtr->SetLastError( 2521 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2522 "SetSendCNPayloadType() failed to register CN to RTP/RTCP " 2523 "module"); 2524 return -1; 2525 } 2526 } 2527 return 0; 2528} 2529 2530WebRtc_Word32 2531Channel::SetISACInitTargetRate(int rateBps, bool useFixedFrameSize) 2532{ 2533 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2534 "Channel::SetISACInitTargetRate()"); 2535 2536 CodecInst sendCodec; 2537 if (_audioCodingModule.SendCodec(sendCodec) == -1) 2538 { 2539 _engineStatisticsPtr->SetLastError( 2540 VE_CODEC_ERROR, kTraceError, 2541 "SetISACInitTargetRate() failed to retrieve send codec"); 2542 return -1; 2543 } 2544 if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2545 { 2546 // This API is only valid if iSAC is setup to run in channel-adaptive 2547 // mode. 2548 // We do not validate the adaptive mode here. It is done later in the 2549 // ConfigISACBandwidthEstimator() API. 2550 _engineStatisticsPtr->SetLastError( 2551 VE_CODEC_ERROR, kTraceError, 2552 "SetISACInitTargetRate() send codec is not iSAC"); 2553 return -1; 2554 } 2555 2556 WebRtc_UWord8 initFrameSizeMsec(0); 2557 if (16000 == sendCodec.plfreq) 2558 { 2559 // Note that 0 is a valid and corresponds to "use default 2560 if ((rateBps != 0 && 2561 rateBps < kVoiceEngineMinIsacInitTargetRateBpsWb) || 2562 (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsWb)) 2563 { 2564 _engineStatisticsPtr->SetLastError( 2565 VE_INVALID_ARGUMENT, kTraceError, 2566 "SetISACInitTargetRate() invalid target rate - 1"); 2567 return -1; 2568 } 2569 // 30 or 60ms 2570 initFrameSizeMsec = (WebRtc_UWord8)(sendCodec.pacsize / 16); 2571 } 2572 else if (32000 == sendCodec.plfreq) 2573 { 2574 if ((rateBps != 0 && 2575 rateBps < kVoiceEngineMinIsacInitTargetRateBpsSwb) || 2576 (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsSwb)) 2577 { 2578 _engineStatisticsPtr->SetLastError( 2579 VE_INVALID_ARGUMENT, kTraceError, 2580 "SetISACInitTargetRate() invalid target rate - 2"); 2581 return -1; 2582 } 2583 initFrameSizeMsec = (WebRtc_UWord8)(sendCodec.pacsize / 32); // 30ms 2584 } 2585 2586 if (_audioCodingModule.ConfigISACBandwidthEstimator( 2587 initFrameSizeMsec, rateBps, useFixedFrameSize) == -1) 2588 { 2589 _engineStatisticsPtr->SetLastError( 2590 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2591 "SetISACInitTargetRate() iSAC BWE config failed"); 2592 return -1; 2593 } 2594 2595 return 0; 2596} 2597 2598WebRtc_Word32 2599Channel::SetISACMaxRate(int rateBps) 2600{ 2601 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2602 "Channel::SetISACMaxRate()"); 2603 2604 CodecInst sendCodec; 2605 if (_audioCodingModule.SendCodec(sendCodec) == -1) 2606 { 2607 _engineStatisticsPtr->SetLastError( 2608 VE_CODEC_ERROR, kTraceError, 2609 "SetISACMaxRate() failed to retrieve send codec"); 2610 return -1; 2611 } 2612 if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2613 { 2614 // This API is only valid if iSAC is selected as sending codec. 2615 _engineStatisticsPtr->SetLastError( 2616 VE_CODEC_ERROR, kTraceError, 2617 "SetISACMaxRate() send codec is not iSAC"); 2618 return -1; 2619 } 2620 if (16000 == sendCodec.plfreq) 2621 { 2622 if ((rateBps < kVoiceEngineMinIsacMaxRateBpsWb) || 2623 (rateBps > kVoiceEngineMaxIsacMaxRateBpsWb)) 2624 { 2625 _engineStatisticsPtr->SetLastError( 2626 VE_INVALID_ARGUMENT, kTraceError, 2627 "SetISACMaxRate() invalid max rate - 1"); 2628 return -1; 2629 } 2630 } 2631 else if (32000 == sendCodec.plfreq) 2632 { 2633 if ((rateBps < kVoiceEngineMinIsacMaxRateBpsSwb) || 2634 (rateBps > kVoiceEngineMaxIsacMaxRateBpsSwb)) 2635 { 2636 _engineStatisticsPtr->SetLastError( 2637 VE_INVALID_ARGUMENT, kTraceError, 2638 "SetISACMaxRate() invalid max rate - 2"); 2639 return -1; 2640 } 2641 } 2642 if (_sending) 2643 { 2644 _engineStatisticsPtr->SetLastError( 2645 VE_SENDING, kTraceError, 2646 "SetISACMaxRate() unable to set max rate while sending"); 2647 return -1; 2648 } 2649 2650 // Set the maximum instantaneous rate of iSAC (works for both adaptive 2651 // and non-adaptive mode) 2652 if (_audioCodingModule.SetISACMaxRate(rateBps) == -1) 2653 { 2654 _engineStatisticsPtr->SetLastError( 2655 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2656 "SetISACMaxRate() failed to set max rate"); 2657 return -1; 2658 } 2659 2660 return 0; 2661} 2662 2663WebRtc_Word32 2664Channel::SetISACMaxPayloadSize(int sizeBytes) 2665{ 2666 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2667 "Channel::SetISACMaxPayloadSize()"); 2668 CodecInst sendCodec; 2669 if (_audioCodingModule.SendCodec(sendCodec) == -1) 2670 { 2671 _engineStatisticsPtr->SetLastError( 2672 VE_CODEC_ERROR, kTraceError, 2673 "SetISACMaxPayloadSize() failed to retrieve send codec"); 2674 return -1; 2675 } 2676 if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2677 { 2678 _engineStatisticsPtr->SetLastError( 2679 VE_CODEC_ERROR, kTraceError, 2680 "SetISACMaxPayloadSize() send codec is not iSAC"); 2681 return -1; 2682 } 2683 if (16000 == sendCodec.plfreq) 2684 { 2685 if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesWb) || 2686 (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesWb)) 2687 { 2688 _engineStatisticsPtr->SetLastError( 2689 VE_INVALID_ARGUMENT, kTraceError, 2690 "SetISACMaxPayloadSize() invalid max payload - 1"); 2691 return -1; 2692 } 2693 } 2694 else if (32000 == sendCodec.plfreq) 2695 { 2696 if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesSwb) || 2697 (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesSwb)) 2698 { 2699 _engineStatisticsPtr->SetLastError( 2700 VE_INVALID_ARGUMENT, kTraceError, 2701 "SetISACMaxPayloadSize() invalid max payload - 2"); 2702 return -1; 2703 } 2704 } 2705 if (_sending) 2706 { 2707 _engineStatisticsPtr->SetLastError( 2708 VE_SENDING, kTraceError, 2709 "SetISACMaxPayloadSize() unable to set max rate while sending"); 2710 return -1; 2711 } 2712 2713 if (_audioCodingModule.SetISACMaxPayloadSize(sizeBytes) == -1) 2714 { 2715 _engineStatisticsPtr->SetLastError( 2716 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2717 "SetISACMaxPayloadSize() failed to set max payload size"); 2718 return -1; 2719 } 2720 return 0; 2721} 2722 2723WebRtc_Word32 Channel::RegisterExternalTransport(Transport& transport) 2724{ 2725 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2726 "Channel::RegisterExternalTransport()"); 2727 2728 CriticalSectionScoped cs(&_callbackCritSect); 2729 2730#ifndef WEBRTC_EXTERNAL_TRANSPORT 2731 // Sanity checks for default (non external transport) to avoid conflict with 2732 // WebRtc sockets. 2733 if (_socketTransportModule.SendSocketsInitialized()) 2734 { 2735 _engineStatisticsPtr->SetLastError(VE_SEND_SOCKETS_CONFLICT, 2736 kTraceError, 2737 "RegisterExternalTransport() send sockets already initialized"); 2738 return -1; 2739 } 2740 if (_socketTransportModule.ReceiveSocketsInitialized()) 2741 { 2742 _engineStatisticsPtr->SetLastError(VE_RECEIVE_SOCKETS_CONFLICT, 2743 kTraceError, 2744 "RegisterExternalTransport() receive sockets already initialized"); 2745 return -1; 2746 } 2747#endif 2748 if (_externalTransport) 2749 { 2750 _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, 2751 kTraceError, 2752 "RegisterExternalTransport() external transport already enabled"); 2753 return -1; 2754 } 2755 _externalTransport = true; 2756 _transportPtr = &transport; 2757 return 0; 2758} 2759 2760WebRtc_Word32 2761Channel::DeRegisterExternalTransport() 2762{ 2763 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2764 "Channel::DeRegisterExternalTransport()"); 2765 2766 CriticalSectionScoped cs(&_callbackCritSect); 2767 2768 if (!_transportPtr) 2769 { 2770 _engineStatisticsPtr->SetLastError( 2771 VE_INVALID_OPERATION, kTraceWarning, 2772 "DeRegisterExternalTransport() external transport already " 2773 "disabled"); 2774 return 0; 2775 } 2776 _externalTransport = false; 2777#ifdef WEBRTC_EXTERNAL_TRANSPORT 2778 _transportPtr = NULL; 2779 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2780 "DeRegisterExternalTransport() all transport is disabled"); 2781#else 2782 _transportPtr = &_socketTransportModule; 2783 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2784 "DeRegisterExternalTransport() internal Transport is enabled"); 2785#endif 2786 return 0; 2787} 2788 2789WebRtc_Word32 2790Channel::ReceivedRTPPacket(const WebRtc_Word8* data, WebRtc_Word32 length) 2791{ 2792 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2793 "Channel::ReceivedRTPPacket()"); 2794 const char dummyIP[] = "127.0.0.1"; 2795 IncomingRTPPacket(data, length, dummyIP, 0); 2796 return 0; 2797} 2798 2799WebRtc_Word32 2800Channel::ReceivedRTCPPacket(const WebRtc_Word8* data, WebRtc_Word32 length) 2801{ 2802 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2803 "Channel::ReceivedRTCPPacket()"); 2804 const char dummyIP[] = "127.0.0.1"; 2805 IncomingRTCPPacket(data, length, dummyIP, 0); 2806 return 0; 2807} 2808 2809#ifndef WEBRTC_EXTERNAL_TRANSPORT 2810WebRtc_Word32 2811Channel::GetSourceInfo(int& rtpPort, int& rtcpPort, char ipAddr[64]) 2812{ 2813 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2814 "Channel::GetSourceInfo()"); 2815 2816 WebRtc_UWord16 rtpPortModule; 2817 WebRtc_UWord16 rtcpPortModule; 2818 char ipaddr[UdpTransport::kIpAddressVersion6Length] = {0}; 2819 2820 if (_socketTransportModule.RemoteSocketInformation(ipaddr, 2821 rtpPortModule, 2822 rtcpPortModule) != 0) 2823 { 2824 _engineStatisticsPtr->SetLastError( 2825 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 2826 "GetSourceInfo() failed to retrieve remote socket information"); 2827 return -1; 2828 } 2829 strcpy(ipAddr, ipaddr); 2830 rtpPort = rtpPortModule; 2831 rtcpPort = rtcpPortModule; 2832 2833 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2834 "GetSourceInfo() => rtpPort=%d, rtcpPort=%d, ipAddr=%s", 2835 rtpPort, rtcpPort, ipAddr); 2836 return 0; 2837} 2838 2839WebRtc_Word32 2840Channel::EnableIPv6() 2841{ 2842 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2843 "Channel::EnableIPv6()"); 2844 if (_socketTransportModule.ReceiveSocketsInitialized() || 2845 _socketTransportModule.SendSocketsInitialized()) 2846 { 2847 _engineStatisticsPtr->SetLastError( 2848 VE_INVALID_OPERATION, kTraceError, 2849 "EnableIPv6() socket layer is already initialized"); 2850 return -1; 2851 } 2852 if (_socketTransportModule.EnableIpV6() != 0) 2853 { 2854 _engineStatisticsPtr->SetLastError( 2855 VE_SOCKET_ERROR, kTraceError, 2856 "EnableIPv6() failed to enable IPv6"); 2857 const UdpTransport::ErrorCode lastError = 2858 _socketTransportModule.LastError(); 2859 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2860 "UdpTransport::LastError() => %d", lastError); 2861 return -1; 2862 } 2863 return 0; 2864} 2865 2866bool 2867Channel::IPv6IsEnabled() const 2868{ 2869 bool isEnabled = _socketTransportModule.IpV6Enabled(); 2870 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2871 "IPv6IsEnabled() => %d", isEnabled); 2872 return isEnabled; 2873} 2874 2875WebRtc_Word32 2876Channel::SetSourceFilter(int rtpPort, int rtcpPort, const char ipAddr[64]) 2877{ 2878 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2879 "Channel::SetSourceFilter()"); 2880 if (_socketTransportModule.SetFilterPorts( 2881 static_cast<WebRtc_UWord16>(rtpPort), 2882 static_cast<WebRtc_UWord16>(rtcpPort)) != 0) 2883 { 2884 _engineStatisticsPtr->SetLastError( 2885 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 2886 "SetSourceFilter() failed to set filter ports"); 2887 const UdpTransport::ErrorCode lastError = 2888 _socketTransportModule.LastError(); 2889 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2890 "UdpTransport::LastError() => %d", 2891 lastError); 2892 return -1; 2893 } 2894 const char* filterIpAddress = ipAddr; 2895 if (_socketTransportModule.SetFilterIP(filterIpAddress) != 0) 2896 { 2897 _engineStatisticsPtr->SetLastError( 2898 VE_INVALID_IP_ADDRESS, kTraceError, 2899 "SetSourceFilter() failed to set filter IP address"); 2900 const UdpTransport::ErrorCode lastError = 2901 _socketTransportModule.LastError(); 2902 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2903 "UdpTransport::LastError() => %d", lastError); 2904 return -1; 2905 } 2906 return 0; 2907} 2908 2909WebRtc_Word32 2910Channel::GetSourceFilter(int& rtpPort, int& rtcpPort, char ipAddr[64]) 2911{ 2912 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2913 "Channel::GetSourceFilter()"); 2914 WebRtc_UWord16 rtpFilterPort(0); 2915 WebRtc_UWord16 rtcpFilterPort(0); 2916 if (_socketTransportModule.FilterPorts(rtpFilterPort, rtcpFilterPort) != 0) 2917 { 2918 _engineStatisticsPtr->SetLastError( 2919 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 2920 "GetSourceFilter() failed to retrieve filter ports"); 2921 } 2922 char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 2923 if (_socketTransportModule.FilterIP(ipAddrTmp) != 0) 2924 { 2925 // no filter has been configured (not seen as an error) 2926 memset(ipAddrTmp, 2927 0, UdpTransport::kIpAddressVersion6Length); 2928 } 2929 rtpPort = static_cast<int> (rtpFilterPort); 2930 rtcpPort = static_cast<int> (rtcpFilterPort); 2931 strcpy(ipAddr, ipAddrTmp); 2932 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2933 "GetSourceFilter() => rtpPort=%d, rtcpPort=%d, ipAddr=%s", 2934 rtpPort, rtcpPort, ipAddr); 2935 return 0; 2936} 2937 2938WebRtc_Word32 2939Channel::SetSendTOS(int DSCP, int priority, bool useSetSockopt) 2940{ 2941 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2942 "Channel::SetSendTOS(DSCP=%d, useSetSockopt=%d)", 2943 DSCP, (int)useSetSockopt); 2944 2945 // Set TOS value and possibly try to force usage of setsockopt() 2946 if (_socketTransportModule.SetToS(DSCP, useSetSockopt) != 0) 2947 { 2948 UdpTransport::ErrorCode lastSockError( 2949 _socketTransportModule.LastError()); 2950 switch (lastSockError) 2951 { 2952 case UdpTransport::kTosError: 2953 _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2954 "SetSendTOS() TOS error"); 2955 break; 2956 case UdpTransport::kQosError: 2957 _engineStatisticsPtr->SetLastError( 2958 VE_TOS_GQOS_CONFLICT, kTraceError, 2959 "SetSendTOS() GQOS error"); 2960 break; 2961 case UdpTransport::kTosInvalid: 2962 // can't switch SetSockOpt method without disabling TOS first, or 2963 // SetSockopt() call failed 2964 _engineStatisticsPtr->SetLastError(VE_TOS_INVALID, kTraceError, 2965 "SetSendTOS() invalid TOS"); 2966 break; 2967 case UdpTransport::kSocketInvalid: 2968 _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError, 2969 "SetSendTOS() invalid Socket"); 2970 break; 2971 default: 2972 _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2973 "SetSendTOS() TOS error"); 2974 break; 2975 } 2976 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2977 "UdpTransport => lastError = %d", 2978 lastSockError); 2979 return -1; 2980 } 2981 2982 // Set priority (PCP) value, -1 means don't change 2983 if (-1 != priority) 2984 { 2985 if (_socketTransportModule.SetPCP(priority) != 0) 2986 { 2987 UdpTransport::ErrorCode lastSockError( 2988 _socketTransportModule.LastError()); 2989 switch (lastSockError) 2990 { 2991 case UdpTransport::kPcpError: 2992 _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2993 "SetSendTOS() PCP error"); 2994 break; 2995 case UdpTransport::kQosError: 2996 _engineStatisticsPtr->SetLastError( 2997 VE_TOS_GQOS_CONFLICT, kTraceError, 2998 "SetSendTOS() GQOS conflict"); 2999 break; 3000 case UdpTransport::kSocketInvalid: 3001 _engineStatisticsPtr->SetLastError( 3002 VE_SOCKET_ERROR, kTraceError, 3003 "SetSendTOS() invalid Socket"); 3004 break; 3005 default: 3006 _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 3007 "SetSendTOS() PCP error"); 3008 break; 3009 } 3010 WEBRTC_TRACE(kTraceError, kTraceVoice, 3011 VoEId(_instanceId,_channelId), 3012 "UdpTransport => lastError = %d", 3013 lastSockError); 3014 return -1; 3015 } 3016 } 3017 3018 return 0; 3019} 3020 3021WebRtc_Word32 3022Channel::GetSendTOS(int &DSCP, int& priority, bool &useSetSockopt) 3023{ 3024 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3025 "Channel::GetSendTOS(DSCP=?, useSetSockopt=?)"); 3026 WebRtc_Word32 dscp(0), prio(0); 3027 bool setSockopt(false); 3028 if (_socketTransportModule.ToS(dscp, setSockopt) != 0) 3029 { 3030 _engineStatisticsPtr->SetLastError( 3031 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3032 "GetSendTOS() failed to get TOS info"); 3033 return -1; 3034 } 3035 if (_socketTransportModule.PCP(prio) != 0) 3036 { 3037 _engineStatisticsPtr->SetLastError( 3038 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3039 "GetSendTOS() failed to get PCP info"); 3040 return -1; 3041 } 3042 DSCP = static_cast<int> (dscp); 3043 priority = static_cast<int> (prio); 3044 useSetSockopt = setSockopt; 3045 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3046 "GetSendTOS() => DSCP=%d, priority=%d, useSetSockopt=%d", 3047 DSCP, priority, (int)useSetSockopt); 3048 return 0; 3049} 3050 3051#if defined(_WIN32) 3052WebRtc_Word32 3053Channel::SetSendGQoS(bool enable, int serviceType, int overrideDSCP) 3054{ 3055 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3056 "Channel::SetSendGQoS(enable=%d, serviceType=%d, " 3057 "overrideDSCP=%d)", 3058 (int)enable, serviceType, overrideDSCP); 3059 if(!_socketTransportModule.ReceiveSocketsInitialized()) 3060 { 3061 _engineStatisticsPtr->SetLastError( 3062 VE_SOCKETS_NOT_INITED, kTraceError, 3063 "SetSendGQoS() GQoS state must be set after sockets are created"); 3064 return -1; 3065 } 3066 if(!_socketTransportModule.SendSocketsInitialized()) 3067 { 3068 _engineStatisticsPtr->SetLastError( 3069 VE_DESTINATION_NOT_INITED, kTraceError, 3070 "SetSendGQoS() GQoS state must be set after sending side is " 3071 "initialized"); 3072 return -1; 3073 } 3074 if (enable && 3075 (serviceType != SERVICETYPE_BESTEFFORT) && 3076 (serviceType != SERVICETYPE_CONTROLLEDLOAD) && 3077 (serviceType != SERVICETYPE_GUARANTEED) && 3078 (serviceType != SERVICETYPE_QUALITATIVE)) 3079 { 3080 _engineStatisticsPtr->SetLastError( 3081 VE_INVALID_ARGUMENT, kTraceError, 3082 "SetSendGQoS() Invalid service type"); 3083 return -1; 3084 } 3085 if (enable && ((overrideDSCP < 0) || (overrideDSCP > 63))) 3086 { 3087 _engineStatisticsPtr->SetLastError( 3088 VE_INVALID_ARGUMENT, kTraceError, 3089 "SetSendGQoS() Invalid overrideDSCP value"); 3090 return -1; 3091 } 3092 3093 // Avoid GQoS/ToS conflict when user wants to override the default DSCP 3094 // mapping 3095 bool QoS(false); 3096 WebRtc_Word32 sType(0); 3097 WebRtc_Word32 ovrDSCP(0); 3098 if (_socketTransportModule.QoS(QoS, sType, ovrDSCP)) 3099 { 3100 _engineStatisticsPtr->SetLastError( 3101 VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3102 "SetSendGQoS() failed to get QOS info"); 3103 return -1; 3104 } 3105 if (QoS && ovrDSCP == 0 && overrideDSCP != 0) 3106 { 3107 _engineStatisticsPtr->SetLastError( 3108 VE_TOS_GQOS_CONFLICT, kTraceError, 3109 "SetSendGQoS() QOS is already enabled and overrideDSCP differs," 3110 " not allowed"); 3111 return -1; 3112 } 3113 const WebRtc_Word32 maxBitrate(0); 3114 if (_socketTransportModule.SetQoS(enable, 3115 static_cast<WebRtc_Word32>(serviceType), 3116 maxBitrate, 3117 static_cast<WebRtc_Word32>(overrideDSCP), 3118 true)) 3119 { 3120 UdpTransport::ErrorCode lastSockError( 3121 _socketTransportModule.LastError()); 3122 switch (lastSockError) 3123 { 3124 case UdpTransport::kQosError: 3125 _engineStatisticsPtr->SetLastError(VE_GQOS_ERROR, kTraceError, 3126 "SetSendGQoS() QOS error"); 3127 break; 3128 default: 3129 _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError, 3130 "SetSendGQoS() Socket error"); 3131 break; 3132 } 3133 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 3134 "UdpTransport() => lastError = %d", 3135 lastSockError); 3136 return -1; 3137 } 3138 return 0; 3139} 3140#endif 3141 3142#if defined(_WIN32) 3143WebRtc_Word32 3144Channel::GetSendGQoS(bool &enabled, int &serviceType, int &overrideDSCP) 3145{ 3146 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3147 "Channel::GetSendGQoS(enable=?, serviceType=?, " 3148 "overrideDSCP=?)"); 3149 3150 bool QoS(false); 3151 WebRtc_Word32 serviceTypeModule(0); 3152 WebRtc_Word32 overrideDSCPModule(0); 3153 _socketTransportModule.QoS(QoS, serviceTypeModule, overrideDSCPModule); 3154 3155 enabled = QoS; 3156 serviceType = static_cast<int> (serviceTypeModule); 3157 overrideDSCP = static_cast<int> (overrideDSCPModule); 3158 3159 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3160 "GetSendGQoS() => enabled=%d, serviceType=%d, overrideDSCP=%d", 3161 (int)enabled, serviceType, overrideDSCP); 3162 return 0; 3163} 3164#endif 3165#endif 3166 3167WebRtc_Word32 3168Channel::SetPacketTimeoutNotification(bool enable, int timeoutSeconds) 3169{ 3170 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3171 "Channel::SetPacketTimeoutNotification()"); 3172 if (enable) 3173 { 3174 const WebRtc_UWord32 RTPtimeoutMS = 1000*timeoutSeconds; 3175 const WebRtc_UWord32 RTCPtimeoutMS = 0; 3176 _rtpRtcpModule->SetPacketTimeout(RTPtimeoutMS, RTCPtimeoutMS); 3177 _rtpPacketTimeOutIsEnabled = true; 3178 _rtpTimeOutSeconds = timeoutSeconds; 3179 } 3180 else 3181 { 3182 _rtpRtcpModule->SetPacketTimeout(0, 0); 3183 _rtpPacketTimeOutIsEnabled = false; 3184 _rtpTimeOutSeconds = 0; 3185 } 3186 return 0; 3187} 3188 3189WebRtc_Word32 3190Channel::GetPacketTimeoutNotification(bool& enabled, int& timeoutSeconds) 3191{ 3192 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3193 "Channel::GetPacketTimeoutNotification()"); 3194 enabled = _rtpPacketTimeOutIsEnabled; 3195 if (enabled) 3196 { 3197 timeoutSeconds = _rtpTimeOutSeconds; 3198 } 3199 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3200 "GetPacketTimeoutNotification() => enabled=%d," 3201 " timeoutSeconds=%d", 3202 enabled, timeoutSeconds); 3203 return 0; 3204} 3205 3206WebRtc_Word32 3207Channel::RegisterDeadOrAliveObserver(VoEConnectionObserver& observer) 3208{ 3209 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3210 "Channel::RegisterDeadOrAliveObserver()"); 3211 CriticalSectionScoped cs(&_callbackCritSect); 3212 3213 if (_connectionObserverPtr) 3214 { 3215 _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, kTraceError, 3216 "RegisterDeadOrAliveObserver() observer already enabled"); 3217 return -1; 3218 } 3219 3220 _connectionObserverPtr = &observer; 3221 _connectionObserver = true; 3222 3223 return 0; 3224} 3225 3226WebRtc_Word32 3227Channel::DeRegisterDeadOrAliveObserver() 3228{ 3229 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3230 "Channel::DeRegisterDeadOrAliveObserver()"); 3231 CriticalSectionScoped cs(&_callbackCritSect); 3232 3233 if (!_connectionObserverPtr) 3234 { 3235 _engineStatisticsPtr->SetLastError( 3236 VE_INVALID_OPERATION, kTraceWarning, 3237 "DeRegisterDeadOrAliveObserver() observer already disabled"); 3238 return 0; 3239 } 3240 3241 _connectionObserver = false; 3242 _connectionObserverPtr = NULL; 3243 3244 return 0; 3245} 3246 3247WebRtc_Word32 3248Channel::SetPeriodicDeadOrAliveStatus(bool enable, int sampleTimeSeconds) 3249{ 3250 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3251 "Channel::SetPeriodicDeadOrAliveStatus()"); 3252 if (!_connectionObserverPtr) 3253 { 3254 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3255 "SetPeriodicDeadOrAliveStatus() connection observer has" 3256 " not been registered"); 3257 } 3258 if (enable) 3259 { 3260 ResetDeadOrAliveCounters(); 3261 } 3262 bool enabled(false); 3263 WebRtc_UWord8 currentSampleTimeSec(0); 3264 // Store last state (will be used later if dead-or-alive is disabled). 3265 _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, currentSampleTimeSec); 3266 // Update the dead-or-alive state. 3267 if (_rtpRtcpModule->SetPeriodicDeadOrAliveStatus( 3268 enable, (WebRtc_UWord8)sampleTimeSeconds) != 0) 3269 { 3270 _engineStatisticsPtr->SetLastError( 3271 VE_RTP_RTCP_MODULE_ERROR, 3272 kTraceError, 3273 "SetPeriodicDeadOrAliveStatus() failed to set dead-or-alive " 3274 "status"); 3275 return -1; 3276 } 3277 if (!enable) 3278 { 3279 // Restore last utilized sample time. 3280 // Without this, the sample time would always be reset to default 3281 // (2 sec), each time dead-or-alived was disabled without sample-time 3282 // parameter. 3283 _rtpRtcpModule->SetPeriodicDeadOrAliveStatus(enable, 3284 currentSampleTimeSec); 3285 } 3286 return 0; 3287} 3288 3289WebRtc_Word32 3290Channel::GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds) 3291{ 3292 _rtpRtcpModule->PeriodicDeadOrAliveStatus( 3293 enabled, 3294 (WebRtc_UWord8&)sampleTimeSeconds); 3295 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3296 "GetPeriodicDeadOrAliveStatus() => enabled=%d," 3297 " sampleTimeSeconds=%d", 3298 enabled, sampleTimeSeconds); 3299 return 0; 3300} 3301 3302WebRtc_Word32 3303Channel::SendUDPPacket(const void* data, 3304 unsigned int length, 3305 int& transmittedBytes, 3306 bool useRtcpSocket) 3307{ 3308 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3309 "Channel::SendUDPPacket()"); 3310 if (_externalTransport) 3311 { 3312 _engineStatisticsPtr->SetLastError( 3313 VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 3314 "SendUDPPacket() external transport is enabled"); 3315 return -1; 3316 } 3317 if (useRtcpSocket && !_rtpRtcpModule->RTCP()) 3318 { 3319 _engineStatisticsPtr->SetLastError( 3320 VE_RTCP_ERROR, kTraceError, 3321 "SendUDPPacket() RTCP is disabled"); 3322 return -1; 3323 } 3324 if (!_sending) 3325 { 3326 _engineStatisticsPtr->SetLastError( 3327 VE_NOT_SENDING, kTraceError, 3328 "SendUDPPacket() not sending"); 3329 return -1; 3330 } 3331 3332 char* dataC = new char[length]; 3333 if (NULL == dataC) 3334 { 3335 _engineStatisticsPtr->SetLastError( 3336 VE_NO_MEMORY, kTraceError, 3337 "SendUDPPacket() memory allocation failed"); 3338 return -1; 3339 } 3340 memcpy(dataC, data, length); 3341 3342 transmittedBytes = SendPacketRaw(dataC, length, useRtcpSocket); 3343 3344 delete [] dataC; 3345 dataC = NULL; 3346 3347 if (transmittedBytes <= 0) 3348 { 3349 _engineStatisticsPtr->SetLastError( 3350 VE_SEND_ERROR, kTraceError, 3351 "SendUDPPacket() transmission failed"); 3352 transmittedBytes = 0; 3353 return -1; 3354 } 3355 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3356 "SendUDPPacket() => transmittedBytes=%d", transmittedBytes); 3357 return 0; 3358} 3359 3360 3361int Channel::StartPlayingFileLocally(const char* fileName, 3362 const bool loop, 3363 const FileFormats format, 3364 const int startPosition, 3365 const float volumeScaling, 3366 const int stopPosition, 3367 const CodecInst* codecInst) 3368{ 3369 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3370 "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," 3371 " format=%d, volumeScaling=%5.3f, startPosition=%d, " 3372 "stopPosition=%d)", fileName, loop, format, volumeScaling, 3373 startPosition, stopPosition); 3374 3375 if (_outputFilePlaying) 3376 { 3377 _engineStatisticsPtr->SetLastError( 3378 VE_ALREADY_PLAYING, kTraceError, 3379 "StartPlayingFileLocally() is already playing"); 3380 return -1; 3381 } 3382 3383 { 3384 CriticalSectionScoped cs(&_fileCritSect); 3385 3386 if (_outputFilePlayerPtr) 3387 { 3388 _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3389 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3390 _outputFilePlayerPtr = NULL; 3391 } 3392 3393 _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3394 _outputFilePlayerId, (const FileFormats)format); 3395 3396 if (_outputFilePlayerPtr == NULL) 3397 { 3398 _engineStatisticsPtr->SetLastError( 3399 VE_INVALID_ARGUMENT, kTraceError, 3400 "StartPlayingFileLocally() filePlayer format is not correct"); 3401 return -1; 3402 } 3403 3404 const WebRtc_UWord32 notificationTime(0); 3405 3406 if (_outputFilePlayerPtr->StartPlayingFile( 3407 fileName, 3408 loop, 3409 startPosition, 3410 volumeScaling, 3411 notificationTime, 3412 stopPosition, 3413 (const CodecInst*)codecInst) != 0) 3414 { 3415 _engineStatisticsPtr->SetLastError( 3416 VE_BAD_FILE, kTraceError, 3417 "StartPlayingFile() failed to start file playout"); 3418 _outputFilePlayerPtr->StopPlayingFile(); 3419 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3420 _outputFilePlayerPtr = NULL; 3421 return -1; 3422 } 3423 _outputFilePlayerPtr->RegisterModuleFileCallback(this); 3424 _outputFilePlaying = true; 3425 } 3426 3427 if (RegisterFilePlayingToMixer() != 0) 3428 return -1; 3429 3430 return 0; 3431} 3432 3433int Channel::StartPlayingFileLocally(InStream* stream, 3434 const FileFormats format, 3435 const int startPosition, 3436 const float volumeScaling, 3437 const int stopPosition, 3438 const CodecInst* codecInst) 3439{ 3440 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3441 "Channel::StartPlayingFileLocally(format=%d," 3442 " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 3443 format, volumeScaling, startPosition, stopPosition); 3444 3445 if(stream == NULL) 3446 { 3447 _engineStatisticsPtr->SetLastError( 3448 VE_BAD_FILE, kTraceError, 3449 "StartPlayingFileLocally() NULL as input stream"); 3450 return -1; 3451 } 3452 3453 3454 if (_outputFilePlaying) 3455 { 3456 _engineStatisticsPtr->SetLastError( 3457 VE_ALREADY_PLAYING, kTraceError, 3458 "StartPlayingFileLocally() is already playing"); 3459 return -1; 3460 } 3461 3462 { 3463 CriticalSectionScoped cs(&_fileCritSect); 3464 3465 // Destroy the old instance 3466 if (_outputFilePlayerPtr) 3467 { 3468 _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3469 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3470 _outputFilePlayerPtr = NULL; 3471 } 3472 3473 // Create the instance 3474 _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3475 _outputFilePlayerId, 3476 (const FileFormats)format); 3477 3478 if (_outputFilePlayerPtr == NULL) 3479 { 3480 _engineStatisticsPtr->SetLastError( 3481 VE_INVALID_ARGUMENT, kTraceError, 3482 "StartPlayingFileLocally() filePlayer format isnot correct"); 3483 return -1; 3484 } 3485 3486 const WebRtc_UWord32 notificationTime(0); 3487 3488 if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 3489 volumeScaling, 3490 notificationTime, 3491 stopPosition, codecInst) != 0) 3492 { 3493 _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3494 "StartPlayingFile() failed to " 3495 "start file playout"); 3496 _outputFilePlayerPtr->StopPlayingFile(); 3497 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3498 _outputFilePlayerPtr = NULL; 3499 return -1; 3500 } 3501 _outputFilePlayerPtr->RegisterModuleFileCallback(this); 3502 _outputFilePlaying = true; 3503 } 3504 3505 if (RegisterFilePlayingToMixer() != 0) 3506 return -1; 3507 3508 return 0; 3509} 3510 3511int Channel::StopPlayingFileLocally() 3512{ 3513 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3514 "Channel::StopPlayingFileLocally()"); 3515 3516 if (!_outputFilePlaying) 3517 { 3518 _engineStatisticsPtr->SetLastError( 3519 VE_INVALID_OPERATION, kTraceWarning, 3520 "StopPlayingFileLocally() isnot playing"); 3521 return 0; 3522 } 3523 3524 { 3525 CriticalSectionScoped cs(&_fileCritSect); 3526 3527 if (_outputFilePlayerPtr->StopPlayingFile() != 0) 3528 { 3529 _engineStatisticsPtr->SetLastError( 3530 VE_STOP_RECORDING_FAILED, kTraceError, 3531 "StopPlayingFile() could not stop playing"); 3532 return -1; 3533 } 3534 _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3535 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3536 _outputFilePlayerPtr = NULL; 3537 _outputFilePlaying = false; 3538 } 3539 // _fileCritSect cannot be taken while calling 3540 // SetAnonymousMixibilityStatus. Refer to comments in 3541 // StartPlayingFileLocally(const char* ...) for more details. 3542 if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) 3543 { 3544 _engineStatisticsPtr->SetLastError( 3545 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 3546 "StopPlayingFile() failed to stop participant from playing as" 3547 "file in the mixer"); 3548 return -1; 3549 } 3550 3551 return 0; 3552} 3553 3554int Channel::IsPlayingFileLocally() const 3555{ 3556 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3557 "Channel::IsPlayingFileLocally()"); 3558 3559 return (WebRtc_Word32)_outputFilePlaying; 3560} 3561 3562int Channel::RegisterFilePlayingToMixer() 3563{ 3564 // Return success for not registering for file playing to mixer if: 3565 // 1. playing file before playout is started on that channel. 3566 // 2. starting playout without file playing on that channel. 3567 if (!_playing || !_outputFilePlaying) 3568 { 3569 return 0; 3570 } 3571 3572 // |_fileCritSect| cannot be taken while calling 3573 // SetAnonymousMixabilityStatus() since as soon as the participant is added 3574 // frames can be pulled by the mixer. Since the frames are generated from 3575 // the file, _fileCritSect will be taken. This would result in a deadlock. 3576 if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) 3577 { 3578 CriticalSectionScoped cs(&_fileCritSect); 3579 _outputFilePlaying = false; 3580 _engineStatisticsPtr->SetLastError( 3581 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 3582 "StartPlayingFile() failed to add participant as file to mixer"); 3583 _outputFilePlayerPtr->StopPlayingFile(); 3584 FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3585 _outputFilePlayerPtr = NULL; 3586 return -1; 3587 } 3588 3589 return 0; 3590} 3591 3592int Channel::ScaleLocalFilePlayout(const float scale) 3593{ 3594 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3595 "Channel::ScaleLocalFilePlayout(scale=%5.3f)", scale); 3596 3597 CriticalSectionScoped cs(&_fileCritSect); 3598 3599 if (!_outputFilePlaying) 3600 { 3601 _engineStatisticsPtr->SetLastError( 3602 VE_INVALID_OPERATION, kTraceError, 3603 "ScaleLocalFilePlayout() isnot playing"); 3604 return -1; 3605 } 3606 if ((_outputFilePlayerPtr == NULL) || 3607 (_outputFilePlayerPtr->SetAudioScaling(scale) != 0)) 3608 { 3609 _engineStatisticsPtr->SetLastError( 3610 VE_BAD_ARGUMENT, kTraceError, 3611 "SetAudioScaling() failed to scale the playout"); 3612 return -1; 3613 } 3614 3615 return 0; 3616} 3617 3618int Channel::GetLocalPlayoutPosition(int& positionMs) 3619{ 3620 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3621 "Channel::GetLocalPlayoutPosition(position=?)"); 3622 3623 WebRtc_UWord32 position; 3624 3625 CriticalSectionScoped cs(&_fileCritSect); 3626 3627 if (_outputFilePlayerPtr == NULL) 3628 { 3629 _engineStatisticsPtr->SetLastError( 3630 VE_INVALID_OPERATION, kTraceError, 3631 "GetLocalPlayoutPosition() filePlayer instance doesnot exist"); 3632 return -1; 3633 } 3634 3635 if (_outputFilePlayerPtr->GetPlayoutPosition(position) != 0) 3636 { 3637 _engineStatisticsPtr->SetLastError( 3638 VE_BAD_FILE, kTraceError, 3639 "GetLocalPlayoutPosition() failed"); 3640 return -1; 3641 } 3642 positionMs = position; 3643 3644 return 0; 3645} 3646 3647int Channel::StartPlayingFileAsMicrophone(const char* fileName, 3648 const bool loop, 3649 const FileFormats format, 3650 const int startPosition, 3651 const float volumeScaling, 3652 const int stopPosition, 3653 const CodecInst* codecInst) 3654{ 3655 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3656 "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " 3657 "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " 3658 "stopPosition=%d)", fileName, loop, format, volumeScaling, 3659 startPosition, stopPosition); 3660 3661 if (_inputFilePlaying) 3662 { 3663 _engineStatisticsPtr->SetLastError( 3664 VE_ALREADY_PLAYING, kTraceWarning, 3665 "StartPlayingFileAsMicrophone() filePlayer is playing"); 3666 return 0; 3667 } 3668 3669 CriticalSectionScoped cs(&_fileCritSect); 3670 3671 // Destroy the old instance 3672 if (_inputFilePlayerPtr) 3673 { 3674 _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3675 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3676 _inputFilePlayerPtr = NULL; 3677 } 3678 3679 // Create the instance 3680 _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3681 _inputFilePlayerId, (const FileFormats)format); 3682 3683 if (_inputFilePlayerPtr == NULL) 3684 { 3685 _engineStatisticsPtr->SetLastError( 3686 VE_INVALID_ARGUMENT, kTraceError, 3687 "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 3688 return -1; 3689 } 3690 3691 const WebRtc_UWord32 notificationTime(0); 3692 3693 if (_inputFilePlayerPtr->StartPlayingFile( 3694 fileName, 3695 loop, 3696 startPosition, 3697 volumeScaling, 3698 notificationTime, 3699 stopPosition, 3700 (const CodecInst*)codecInst) != 0) 3701 { 3702 _engineStatisticsPtr->SetLastError( 3703 VE_BAD_FILE, kTraceError, 3704 "StartPlayingFile() failed to start file playout"); 3705 _inputFilePlayerPtr->StopPlayingFile(); 3706 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3707 _inputFilePlayerPtr = NULL; 3708 return -1; 3709 } 3710 _inputFilePlayerPtr->RegisterModuleFileCallback(this); 3711 _inputFilePlaying = true; 3712 3713 return 0; 3714} 3715 3716int Channel::StartPlayingFileAsMicrophone(InStream* stream, 3717 const FileFormats format, 3718 const int startPosition, 3719 const float volumeScaling, 3720 const int stopPosition, 3721 const CodecInst* codecInst) 3722{ 3723 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3724 "Channel::StartPlayingFileAsMicrophone(format=%d, " 3725 "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 3726 format, volumeScaling, startPosition, stopPosition); 3727 3728 if(stream == NULL) 3729 { 3730 _engineStatisticsPtr->SetLastError( 3731 VE_BAD_FILE, kTraceError, 3732 "StartPlayingFileAsMicrophone NULL as input stream"); 3733 return -1; 3734 } 3735 3736 if (_inputFilePlaying) 3737 { 3738 _engineStatisticsPtr->SetLastError( 3739 VE_ALREADY_PLAYING, kTraceWarning, 3740 "StartPlayingFileAsMicrophone() is playing"); 3741 return 0; 3742 } 3743 3744 CriticalSectionScoped cs(&_fileCritSect); 3745 3746 // Destroy the old instance 3747 if (_inputFilePlayerPtr) 3748 { 3749 _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3750 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3751 _inputFilePlayerPtr = NULL; 3752 } 3753 3754 // Create the instance 3755 _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3756 _inputFilePlayerId, (const FileFormats)format); 3757 3758 if (_inputFilePlayerPtr == NULL) 3759 { 3760 _engineStatisticsPtr->SetLastError( 3761 VE_INVALID_ARGUMENT, kTraceError, 3762 "StartPlayingInputFile() filePlayer format isnot correct"); 3763 return -1; 3764 } 3765 3766 const WebRtc_UWord32 notificationTime(0); 3767 3768 if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 3769 volumeScaling, notificationTime, 3770 stopPosition, codecInst) != 0) 3771 { 3772 _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3773 "StartPlayingFile() failed to start " 3774 "file playout"); 3775 _inputFilePlayerPtr->StopPlayingFile(); 3776 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3777 _inputFilePlayerPtr = NULL; 3778 return -1; 3779 } 3780 3781 _inputFilePlayerPtr->RegisterModuleFileCallback(this); 3782 _inputFilePlaying = true; 3783 3784 return 0; 3785} 3786 3787int Channel::StopPlayingFileAsMicrophone() 3788{ 3789 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3790 "Channel::StopPlayingFileAsMicrophone()"); 3791 3792 if (!_inputFilePlaying) 3793 { 3794 _engineStatisticsPtr->SetLastError( 3795 VE_INVALID_OPERATION, kTraceWarning, 3796 "StopPlayingFileAsMicrophone() isnot playing"); 3797 return 0; 3798 } 3799 3800 CriticalSectionScoped cs(&_fileCritSect); 3801 if (_inputFilePlayerPtr->StopPlayingFile() != 0) 3802 { 3803 _engineStatisticsPtr->SetLastError( 3804 VE_STOP_RECORDING_FAILED, kTraceError, 3805 "StopPlayingFile() could not stop playing"); 3806 return -1; 3807 } 3808 _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3809 FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3810 _inputFilePlayerPtr = NULL; 3811 _inputFilePlaying = false; 3812 3813 return 0; 3814} 3815 3816int Channel::IsPlayingFileAsMicrophone() const 3817{ 3818 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3819 "Channel::IsPlayingFileAsMicrophone()"); 3820 3821 return _inputFilePlaying; 3822} 3823 3824int Channel::ScaleFileAsMicrophonePlayout(const float scale) 3825{ 3826 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3827 "Channel::ScaleFileAsMicrophonePlayout(scale=%5.3f)", scale); 3828 3829 CriticalSectionScoped cs(&_fileCritSect); 3830 3831 if (!_inputFilePlaying) 3832 { 3833 _engineStatisticsPtr->SetLastError( 3834 VE_INVALID_OPERATION, kTraceError, 3835 "ScaleFileAsMicrophonePlayout() isnot playing"); 3836 return -1; 3837 } 3838 3839 if ((_inputFilePlayerPtr == NULL) || 3840 (_inputFilePlayerPtr->SetAudioScaling(scale) != 0)) 3841 { 3842 _engineStatisticsPtr->SetLastError( 3843 VE_BAD_ARGUMENT, kTraceError, 3844 "SetAudioScaling() failed to scale playout"); 3845 return -1; 3846 } 3847 3848 return 0; 3849} 3850 3851int Channel::StartRecordingPlayout(const char* fileName, 3852 const CodecInst* codecInst) 3853{ 3854 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3855 "Channel::StartRecordingPlayout(fileName=%s)", fileName); 3856 3857 if (_outputFileRecording) 3858 { 3859 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 3860 "StartRecordingPlayout() is already recording"); 3861 return 0; 3862 } 3863 3864 FileFormats format; 3865 const WebRtc_UWord32 notificationTime(0); // Not supported in VoE 3866 CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 3867 3868 if ((codecInst != NULL) && 3869 ((codecInst->channels < 1) || (codecInst->channels > 2))) 3870 { 3871 _engineStatisticsPtr->SetLastError( 3872 VE_BAD_ARGUMENT, kTraceError, 3873 "StartRecordingPlayout() invalid compression"); 3874 return(-1); 3875 } 3876 if(codecInst == NULL) 3877 { 3878 format = kFileFormatPcm16kHzFile; 3879 codecInst=&dummyCodec; 3880 } 3881 else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 3882 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 3883 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 3884 { 3885 format = kFileFormatWavFile; 3886 } 3887 else 3888 { 3889 format = kFileFormatCompressedFile; 3890 } 3891 3892 CriticalSectionScoped cs(&_fileCritSect); 3893 3894 // Destroy the old instance 3895 if (_outputFileRecorderPtr) 3896 { 3897 _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 3898 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3899 _outputFileRecorderPtr = NULL; 3900 } 3901 3902 _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 3903 _outputFileRecorderId, (const FileFormats)format); 3904 if (_outputFileRecorderPtr == NULL) 3905 { 3906 _engineStatisticsPtr->SetLastError( 3907 VE_INVALID_ARGUMENT, kTraceError, 3908 "StartRecordingPlayout() fileRecorder format isnot correct"); 3909 return -1; 3910 } 3911 3912 if (_outputFileRecorderPtr->StartRecordingAudioFile( 3913 fileName, (const CodecInst&)*codecInst, notificationTime) != 0) 3914 { 3915 _engineStatisticsPtr->SetLastError( 3916 VE_BAD_FILE, kTraceError, 3917 "StartRecordingAudioFile() failed to start file recording"); 3918 _outputFileRecorderPtr->StopRecording(); 3919 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3920 _outputFileRecorderPtr = NULL; 3921 return -1; 3922 } 3923 _outputFileRecorderPtr->RegisterModuleFileCallback(this); 3924 _outputFileRecording = true; 3925 3926 return 0; 3927} 3928 3929int Channel::StartRecordingPlayout(OutStream* stream, 3930 const CodecInst* codecInst) 3931{ 3932 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3933 "Channel::StartRecordingPlayout()"); 3934 3935 if (_outputFileRecording) 3936 { 3937 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 3938 "StartRecordingPlayout() is already recording"); 3939 return 0; 3940 } 3941 3942 FileFormats format; 3943 const WebRtc_UWord32 notificationTime(0); // Not supported in VoE 3944 CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 3945 3946 if (codecInst != NULL && codecInst->channels != 1) 3947 { 3948 _engineStatisticsPtr->SetLastError( 3949 VE_BAD_ARGUMENT, kTraceError, 3950 "StartRecordingPlayout() invalid compression"); 3951 return(-1); 3952 } 3953 if(codecInst == NULL) 3954 { 3955 format = kFileFormatPcm16kHzFile; 3956 codecInst=&dummyCodec; 3957 } 3958 else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 3959 (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 3960 (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 3961 { 3962 format = kFileFormatWavFile; 3963 } 3964 else 3965 { 3966 format = kFileFormatCompressedFile; 3967 } 3968 3969 CriticalSectionScoped cs(&_fileCritSect); 3970 3971 // Destroy the old instance 3972 if (_outputFileRecorderPtr) 3973 { 3974 _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 3975 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3976 _outputFileRecorderPtr = NULL; 3977 } 3978 3979 _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 3980 _outputFileRecorderId, (const FileFormats)format); 3981 if (_outputFileRecorderPtr == NULL) 3982 { 3983 _engineStatisticsPtr->SetLastError( 3984 VE_INVALID_ARGUMENT, kTraceError, 3985 "StartRecordingPlayout() fileRecorder format isnot correct"); 3986 return -1; 3987 } 3988 3989 if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, 3990 notificationTime) != 0) 3991 { 3992 _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3993 "StartRecordingPlayout() failed to " 3994 "start file recording"); 3995 _outputFileRecorderPtr->StopRecording(); 3996 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3997 _outputFileRecorderPtr = NULL; 3998 return -1; 3999 } 4000 4001 _outputFileRecorderPtr->RegisterModuleFileCallback(this); 4002 _outputFileRecording = true; 4003 4004 return 0; 4005} 4006 4007int Channel::StopRecordingPlayout() 4008{ 4009 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 4010 "Channel::StopRecordingPlayout()"); 4011 4012 if (!_outputFileRecording) 4013 { 4014 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), 4015 "StopRecordingPlayout() isnot recording"); 4016 return -1; 4017 } 4018 4019 4020 CriticalSectionScoped cs(&_fileCritSect); 4021 4022 if (_outputFileRecorderPtr->StopRecording() != 0) 4023 { 4024 _engineStatisticsPtr->SetLastError( 4025 VE_STOP_RECORDING_FAILED, kTraceError, 4026 "StopRecording() could not stop recording"); 4027 return(-1); 4028 } 4029 _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 4030 FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 4031 _outputFileRecorderPtr = NULL; 4032 _outputFileRecording = false; 4033 4034 return 0; 4035} 4036 4037void 4038Channel::SetMixWithMicStatus(bool mix) 4039{ 4040 _mixFileWithMicrophone=mix; 4041} 4042 4043int 4044Channel::GetSpeechOutputLevel(WebRtc_UWord32& level) const 4045{ 4046 WebRtc_Word8 currentLevel = _outputAudioLevel.Level(); 4047 level = static_cast<WebRtc_Word32> (currentLevel); 4048 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4049 VoEId(_instanceId,_channelId), 4050 "GetSpeechOutputLevel() => level=%u", level); 4051 return 0; 4052} 4053 4054int 4055Channel::GetSpeechOutputLevelFullRange(WebRtc_UWord32& level) const 4056{ 4057 WebRtc_Word16 currentLevel = _outputAudioLevel.LevelFullRange(); 4058 level = static_cast<WebRtc_Word32> (currentLevel); 4059 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4060 VoEId(_instanceId,_channelId), 4061 "GetSpeechOutputLevelFullRange() => level=%u", level); 4062 return 0; 4063} 4064 4065int 4066Channel::SetMute(bool enable) 4067{ 4068 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4069 "Channel::SetMute(enable=%d)", enable); 4070 _mute = enable; 4071 return 0; 4072} 4073 4074bool 4075Channel::Mute() const 4076{ 4077 return _mute; 4078} 4079 4080int 4081Channel::SetOutputVolumePan(float left, float right) 4082{ 4083 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4084 "Channel::SetOutputVolumePan()"); 4085 _panLeft = left; 4086 _panRight = right; 4087 return 0; 4088} 4089 4090int 4091Channel::GetOutputVolumePan(float& left, float& right) const 4092{ 4093 left = _panLeft; 4094 right = _panRight; 4095 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4096 VoEId(_instanceId,_channelId), 4097 "GetOutputVolumePan() => left=%3.2f, right=%3.2f", left, right); 4098 return 0; 4099} 4100 4101int 4102Channel::SetChannelOutputVolumeScaling(float scaling) 4103{ 4104 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4105 "Channel::SetChannelOutputVolumeScaling()"); 4106 _outputGain = scaling; 4107 return 0; 4108} 4109 4110int 4111Channel::GetChannelOutputVolumeScaling(float& scaling) const 4112{ 4113 scaling = _outputGain; 4114 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4115 VoEId(_instanceId,_channelId), 4116 "GetChannelOutputVolumeScaling() => scaling=%3.2f", scaling); 4117 return 0; 4118} 4119 4120#ifdef WEBRTC_SRTP 4121 4122int 4123Channel::EnableSRTPSend( 4124 CipherTypes cipherType, 4125 int cipherKeyLength, 4126 AuthenticationTypes authType, 4127 int authKeyLength, 4128 int authTagLength, 4129 SecurityLevels level, 4130 const unsigned char key[kVoiceEngineMaxSrtpKeyLength], 4131 bool useForRTCP) 4132{ 4133 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4134 "Channel::EnableSRTPSend()"); 4135 4136 CriticalSectionScoped cs(&_callbackCritSect); 4137 4138 if (_encrypting) 4139 { 4140 _engineStatisticsPtr->SetLastError( 4141 VE_INVALID_OPERATION, kTraceWarning, 4142 "EnableSRTPSend() encryption already enabled"); 4143 return -1; 4144 } 4145 4146 if (key == NULL) 4147 { 4148 _engineStatisticsPtr->SetLastError( 4149 VE_INVALID_ARGUMENT, kTraceWarning, 4150 "EnableSRTPSend() invalid key string"); 4151 return -1; 4152 } 4153 4154 if (((kEncryption == level || 4155 kEncryptionAndAuthentication == level) && 4156 (cipherKeyLength < kVoiceEngineMinSrtpEncryptLength || 4157 cipherKeyLength > kVoiceEngineMaxSrtpEncryptLength)) || 4158 ((kAuthentication == level || 4159 kEncryptionAndAuthentication == level) && 4160 kAuthHmacSha1 == authType && 4161 (authKeyLength > kVoiceEngineMaxSrtpAuthSha1Length || 4162 authTagLength > kVoiceEngineMaxSrtpAuthSha1Length)) || 4163 ((kAuthentication == level || 4164 kEncryptionAndAuthentication == level) && 4165 kAuthNull == authType && 4166 (authKeyLength > kVoiceEngineMaxSrtpKeyAuthNullLength || 4167 authTagLength > kVoiceEngineMaxSrtpTagAuthNullLength))) 4168 { 4169 _engineStatisticsPtr->SetLastError( 4170 VE_INVALID_ARGUMENT, kTraceError, 4171 "EnableSRTPSend() invalid key length(s)"); 4172 return -1; 4173 } 4174 4175 4176 if (_srtpModule.EnableSRTPEncrypt( 4177 !useForRTCP, 4178 (SrtpModule::CipherTypes)cipherType, 4179 cipherKeyLength, 4180 (SrtpModule::AuthenticationTypes)authType, 4181 authKeyLength, authTagLength, 4182 (SrtpModule::SecurityLevels)level, 4183 key) == -1) 4184 { 4185 _engineStatisticsPtr->SetLastError( 4186 VE_SRTP_ERROR, kTraceError, 4187 "EnableSRTPSend() failed to enable SRTP encryption"); 4188 return -1; 4189 } 4190 4191 if (_encryptionPtr == NULL) 4192 { 4193 _encryptionPtr = &_srtpModule; 4194 } 4195 _encrypting = true; 4196 4197 return 0; 4198} 4199 4200int 4201Channel::DisableSRTPSend() 4202{ 4203 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4204 "Channel::DisableSRTPSend()"); 4205 4206 CriticalSectionScoped cs(&_callbackCritSect); 4207 4208 if (!_encrypting) 4209 { 4210 _engineStatisticsPtr->SetLastError( 4211 VE_INVALID_OPERATION, kTraceWarning, 4212 "DisableSRTPSend() SRTP encryption already disabled"); 4213 return 0; 4214 } 4215 4216 _encrypting = false; 4217 4218 if (_srtpModule.DisableSRTPEncrypt() == -1) 4219 { 4220 _engineStatisticsPtr->SetLastError( 4221 VE_SRTP_ERROR, kTraceError, 4222 "DisableSRTPSend() failed to disable SRTP encryption"); 4223 return -1; 4224 } 4225 4226 if (!_srtpModule.SRTPDecrypt() && !_srtpModule.SRTPEncrypt()) 4227 { 4228 // Both directions are disabled 4229 _encryptionPtr = NULL; 4230 } 4231 4232 return 0; 4233} 4234 4235int 4236Channel::EnableSRTPReceive( 4237 CipherTypes cipherType, 4238 int cipherKeyLength, 4239 AuthenticationTypes authType, 4240 int authKeyLength, 4241 int authTagLength, 4242 SecurityLevels level, 4243 const unsigned char key[kVoiceEngineMaxSrtpKeyLength], 4244 bool useForRTCP) 4245{ 4246 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4247 "Channel::EnableSRTPReceive()"); 4248 4249 CriticalSectionScoped cs(&_callbackCritSect); 4250 4251 if (_decrypting) 4252 { 4253 _engineStatisticsPtr->SetLastError( 4254 VE_INVALID_OPERATION, kTraceWarning, 4255 "EnableSRTPReceive() SRTP decryption already enabled"); 4256 return -1; 4257 } 4258 4259 if (key == NULL) 4260 { 4261 _engineStatisticsPtr->SetLastError( 4262 VE_INVALID_ARGUMENT, kTraceWarning, 4263 "EnableSRTPReceive() invalid key string"); 4264 return -1; 4265 } 4266 4267 if ((((kEncryption == level) || 4268 (kEncryptionAndAuthentication == level)) && 4269 ((cipherKeyLength < kVoiceEngineMinSrtpEncryptLength) || 4270 (cipherKeyLength > kVoiceEngineMaxSrtpEncryptLength))) || 4271 (((kAuthentication == level) || 4272 (kEncryptionAndAuthentication == level)) && 4273 (kAuthHmacSha1 == authType) && 4274 ((authKeyLength > kVoiceEngineMaxSrtpAuthSha1Length) || 4275 (authTagLength > kVoiceEngineMaxSrtpAuthSha1Length))) || 4276 (((kAuthentication == level) || 4277 (kEncryptionAndAuthentication == level)) && 4278 (kAuthNull == authType) && 4279 ((authKeyLength > kVoiceEngineMaxSrtpKeyAuthNullLength) || 4280 (authTagLength > kVoiceEngineMaxSrtpTagAuthNullLength)))) 4281 { 4282 _engineStatisticsPtr->SetLastError( 4283 VE_INVALID_ARGUMENT, kTraceError, 4284 "EnableSRTPReceive() invalid key length(s)"); 4285 return -1; 4286 } 4287 4288 if (_srtpModule.EnableSRTPDecrypt( 4289 !useForRTCP, 4290 (SrtpModule::CipherTypes)cipherType, 4291 cipherKeyLength, 4292 (SrtpModule::AuthenticationTypes)authType, 4293 authKeyLength, 4294 authTagLength, 4295 (SrtpModule::SecurityLevels)level, 4296 key) == -1) 4297 { 4298 _engineStatisticsPtr->SetLastError( 4299 VE_SRTP_ERROR, kTraceError, 4300 "EnableSRTPReceive() failed to enable SRTP decryption"); 4301 return -1; 4302 } 4303 4304 if (_encryptionPtr == NULL) 4305 { 4306 _encryptionPtr = &_srtpModule; 4307 } 4308 4309 _decrypting = true; 4310 4311 return 0; 4312} 4313 4314int 4315Channel::DisableSRTPReceive() 4316{ 4317 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4318 "Channel::DisableSRTPReceive()"); 4319 4320 CriticalSectionScoped cs(&_callbackCritSect); 4321 4322 if (!_decrypting) 4323 { 4324 _engineStatisticsPtr->SetLastError( 4325 VE_INVALID_OPERATION, kTraceWarning, 4326 "DisableSRTPReceive() SRTP decryption already disabled"); 4327 return 0; 4328 } 4329 4330 _decrypting = false; 4331 4332 if (_srtpModule.DisableSRTPDecrypt() == -1) 4333 { 4334 _engineStatisticsPtr->SetLastError( 4335 VE_SRTP_ERROR, kTraceError, 4336 "DisableSRTPReceive() failed to disable SRTP decryption"); 4337 return -1; 4338 } 4339 4340 if (!_srtpModule.SRTPDecrypt() && !_srtpModule.SRTPEncrypt()) 4341 { 4342 _encryptionPtr = NULL; 4343 } 4344 4345 return 0; 4346} 4347 4348#endif 4349 4350int 4351Channel::RegisterExternalEncryption(Encryption& encryption) 4352{ 4353 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4354 "Channel::RegisterExternalEncryption()"); 4355 4356 CriticalSectionScoped cs(&_callbackCritSect); 4357 4358 if (_encryptionPtr) 4359 { 4360 _engineStatisticsPtr->SetLastError( 4361 VE_INVALID_OPERATION, kTraceError, 4362 "RegisterExternalEncryption() encryption already enabled"); 4363 return -1; 4364 } 4365 4366 _encryptionPtr = &encryption; 4367 4368 _decrypting = true; 4369 _encrypting = true; 4370 4371 return 0; 4372} 4373 4374int 4375Channel::DeRegisterExternalEncryption() 4376{ 4377 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4378 "Channel::DeRegisterExternalEncryption()"); 4379 4380 CriticalSectionScoped cs(&_callbackCritSect); 4381 4382 if (!_encryptionPtr) 4383 { 4384 _engineStatisticsPtr->SetLastError( 4385 VE_INVALID_OPERATION, kTraceWarning, 4386 "DeRegisterExternalEncryption() encryption already disabled"); 4387 return 0; 4388 } 4389 4390 _decrypting = false; 4391 _encrypting = false; 4392 4393 _encryptionPtr = NULL; 4394 4395 return 0; 4396} 4397 4398int Channel::SendTelephoneEventOutband(unsigned char eventCode, 4399 int lengthMs, int attenuationDb, 4400 bool playDtmfEvent) 4401{ 4402 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4403 "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", 4404 playDtmfEvent); 4405 4406 _playOutbandDtmfEvent = playDtmfEvent; 4407 4408 if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, 4409 attenuationDb) != 0) 4410 { 4411 _engineStatisticsPtr->SetLastError( 4412 VE_SEND_DTMF_FAILED, 4413 kTraceWarning, 4414 "SendTelephoneEventOutband() failed to send event"); 4415 return -1; 4416 } 4417 return 0; 4418} 4419 4420int Channel::SendTelephoneEventInband(unsigned char eventCode, 4421 int lengthMs, 4422 int attenuationDb, 4423 bool playDtmfEvent) 4424{ 4425 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4426 "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", 4427 playDtmfEvent); 4428 4429 _playInbandDtmfEvent = playDtmfEvent; 4430 _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); 4431 4432 return 0; 4433} 4434 4435int 4436Channel::SetDtmfPlayoutStatus(bool enable) 4437{ 4438 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4439 "Channel::SetDtmfPlayoutStatus()"); 4440 if (_audioCodingModule.SetDtmfPlayoutStatus(enable) != 0) 4441 { 4442 _engineStatisticsPtr->SetLastError( 4443 VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 4444 "SetDtmfPlayoutStatus() failed to set Dtmf playout"); 4445 return -1; 4446 } 4447 return 0; 4448} 4449 4450bool 4451Channel::DtmfPlayoutStatus() const 4452{ 4453 return _audioCodingModule.DtmfPlayoutStatus(); 4454} 4455 4456int 4457Channel::SetSendTelephoneEventPayloadType(unsigned char type) 4458{ 4459 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4460 "Channel::SetSendTelephoneEventPayloadType()"); 4461 if (type > 127) 4462 { 4463 _engineStatisticsPtr->SetLastError( 4464 VE_INVALID_ARGUMENT, kTraceError, 4465 "SetSendTelephoneEventPayloadType() invalid type"); 4466 return -1; 4467 } 4468 CodecInst codec; 4469 codec.plfreq = 8000; 4470 codec.pltype = type; 4471 memcpy(codec.plname, "telephone-event", 16); 4472 if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 4473 { 4474 _engineStatisticsPtr->SetLastError( 4475 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4476 "SetSendTelephoneEventPayloadType() failed to register send" 4477 "payload type"); 4478 return -1; 4479 } 4480 _sendTelephoneEventPayloadType = type; 4481 return 0; 4482} 4483 4484int 4485Channel::GetSendTelephoneEventPayloadType(unsigned char& type) 4486{ 4487 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4488 "Channel::GetSendTelephoneEventPayloadType()"); 4489 type = _sendTelephoneEventPayloadType; 4490 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4491 VoEId(_instanceId,_channelId), 4492 "GetSendTelephoneEventPayloadType() => type=%u", type); 4493 return 0; 4494} 4495 4496#ifdef WEBRTC_DTMF_DETECTION 4497 4498WebRtc_Word32 4499Channel::RegisterTelephoneEventDetection( 4500 TelephoneEventDetectionMethods detectionMethod, 4501 VoETelephoneEventObserver& observer) 4502{ 4503 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4504 "Channel::RegisterTelephoneEventDetection()"); 4505 CriticalSectionScoped cs(&_callbackCritSect); 4506 4507 if (_telephoneEventDetectionPtr) 4508 { 4509 _engineStatisticsPtr->SetLastError( 4510 VE_INVALID_OPERATION, kTraceError, 4511 "RegisterTelephoneEventDetection() detection already enabled"); 4512 return -1; 4513 } 4514 4515 _telephoneEventDetectionPtr = &observer; 4516 4517 switch (detectionMethod) 4518 { 4519 case kInBand: 4520 _inbandTelephoneEventDetection = true; 4521 _outOfBandTelephoneEventDetecion = false; 4522 break; 4523 case kOutOfBand: 4524 _inbandTelephoneEventDetection = false; 4525 _outOfBandTelephoneEventDetecion = true; 4526 break; 4527 case kInAndOutOfBand: 4528 _inbandTelephoneEventDetection = true; 4529 _outOfBandTelephoneEventDetecion = true; 4530 break; 4531 default: 4532 _engineStatisticsPtr->SetLastError( 4533 VE_INVALID_ARGUMENT, kTraceError, 4534 "RegisterTelephoneEventDetection() invalid detection method"); 4535 return -1; 4536 } 4537 4538 if (_inbandTelephoneEventDetection) 4539 { 4540 // Enable in-band Dtmf detectin in the ACM. 4541 if (_audioCodingModule.RegisterIncomingMessagesCallback(this) != 0) 4542 { 4543 _engineStatisticsPtr->SetLastError( 4544 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 4545 "RegisterTelephoneEventDetection() failed to enable Dtmf " 4546 "detection"); 4547 } 4548 } 4549 4550 // Enable/disable out-of-band detection of received telephone-events. 4551 // When enabled, RtpAudioFeedback::OnReceivedTelephoneEvent() will be 4552 // called two times by the RTP/RTCP module (start & end). 4553 const bool forwardToDecoder = 4554 _rtpRtcpModule->TelephoneEventForwardToDecoder(); 4555 const bool detectEndOfTone = true; 4556 _rtpRtcpModule->SetTelephoneEventStatus(_outOfBandTelephoneEventDetecion, 4557 forwardToDecoder, 4558 detectEndOfTone); 4559 4560 return 0; 4561} 4562 4563int 4564Channel::DeRegisterTelephoneEventDetection() 4565{ 4566 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4567 "Channel::DeRegisterTelephoneEventDetection()"); 4568 4569 CriticalSectionScoped cs(&_callbackCritSect); 4570 4571 if (!_telephoneEventDetectionPtr) 4572 { 4573 _engineStatisticsPtr->SetLastError( 4574 VE_INVALID_OPERATION, 4575 kTraceWarning, 4576 "DeRegisterTelephoneEventDetection() detection already disabled"); 4577 return 0; 4578 } 4579 4580 // Disable out-of-band event detection 4581 const bool forwardToDecoder = 4582 _rtpRtcpModule->TelephoneEventForwardToDecoder(); 4583 _rtpRtcpModule->SetTelephoneEventStatus(false, forwardToDecoder); 4584 4585 // Disable in-band Dtmf detection 4586 _audioCodingModule.RegisterIncomingMessagesCallback(NULL); 4587 4588 _inbandTelephoneEventDetection = false; 4589 _outOfBandTelephoneEventDetecion = false; 4590 _telephoneEventDetectionPtr = NULL; 4591 4592 return 0; 4593} 4594 4595int 4596Channel::GetTelephoneEventDetectionStatus( 4597 bool& enabled, 4598 TelephoneEventDetectionMethods& detectionMethod) 4599{ 4600 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4601 "Channel::GetTelephoneEventDetectionStatus()"); 4602 4603 { 4604 CriticalSectionScoped cs(&_callbackCritSect); 4605 enabled = (_telephoneEventDetectionPtr != NULL); 4606 } 4607 4608 if (enabled) 4609 { 4610 if (_inbandTelephoneEventDetection && !_outOfBandTelephoneEventDetecion) 4611 detectionMethod = kInBand; 4612 else if (!_inbandTelephoneEventDetection 4613 && _outOfBandTelephoneEventDetecion) 4614 detectionMethod = kOutOfBand; 4615 else if (_inbandTelephoneEventDetection 4616 && _outOfBandTelephoneEventDetecion) 4617 detectionMethod = kInAndOutOfBand; 4618 else 4619 { 4620 assert(false); 4621 return -1; 4622 } 4623 } 4624 4625 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4626 VoEId(_instanceId, _channelId), 4627 "GetTelephoneEventDetectionStatus() => enabled=%d," 4628 "detectionMethod=%d", enabled, detectionMethod); 4629 return 0; 4630} 4631 4632#endif // #ifdef WEBRTC_DTMF_DETECTION 4633 4634int 4635Channel::UpdateRxVadDetection(AudioFrame& audioFrame) 4636{ 4637 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4638 "Channel::UpdateRxVadDetection()"); 4639 4640 int vadDecision = 1; 4641 4642 vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; 4643 4644 if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) 4645 { 4646 OnRxVadDetected(vadDecision); 4647 _oldVadDecision = vadDecision; 4648 } 4649 4650 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4651 "Channel::UpdateRxVadDetection() => vadDecision=%d", 4652 vadDecision); 4653 return 0; 4654} 4655 4656int 4657Channel::RegisterRxVadObserver(VoERxVadCallback &observer) 4658{ 4659 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4660 "Channel::RegisterRxVadObserver()"); 4661 CriticalSectionScoped cs(&_callbackCritSect); 4662 4663 if (_rxVadObserverPtr) 4664 { 4665 _engineStatisticsPtr->SetLastError( 4666 VE_INVALID_OPERATION, kTraceError, 4667 "RegisterRxVadObserver() observer already enabled"); 4668 return -1; 4669 } 4670 _rxVadObserverPtr = &observer; 4671 _RxVadDetection = true; 4672 return 0; 4673} 4674 4675int 4676Channel::DeRegisterRxVadObserver() 4677{ 4678 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4679 "Channel::DeRegisterRxVadObserver()"); 4680 CriticalSectionScoped cs(&_callbackCritSect); 4681 4682 if (!_rxVadObserverPtr) 4683 { 4684 _engineStatisticsPtr->SetLastError( 4685 VE_INVALID_OPERATION, kTraceWarning, 4686 "DeRegisterRxVadObserver() observer already disabled"); 4687 return 0; 4688 } 4689 _rxVadObserverPtr = NULL; 4690 _RxVadDetection = false; 4691 return 0; 4692} 4693 4694int 4695Channel::VoiceActivityIndicator(int &activity) 4696{ 4697 activity = _sendFrameType; 4698 4699 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4700 "Channel::VoiceActivityIndicator(indicator=%d)", activity); 4701 return 0; 4702} 4703 4704#ifdef WEBRTC_VOICE_ENGINE_AGC 4705 4706int 4707Channel::SetRxAgcStatus(const bool enable, const AgcModes mode) 4708{ 4709 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4710 "Channel::SetRxAgcStatus(enable=%d, mode=%d)", 4711 (int)enable, (int)mode); 4712 4713 GainControl::Mode agcMode(GainControl::kFixedDigital); 4714 switch (mode) 4715 { 4716 case kAgcDefault: 4717 agcMode = GainControl::kAdaptiveDigital; 4718 break; 4719 case kAgcUnchanged: 4720 agcMode = _rxAudioProcessingModulePtr->gain_control()->mode(); 4721 break; 4722 case kAgcFixedDigital: 4723 agcMode = GainControl::kFixedDigital; 4724 break; 4725 case kAgcAdaptiveDigital: 4726 agcMode =GainControl::kAdaptiveDigital; 4727 break; 4728 default: 4729 _engineStatisticsPtr->SetLastError( 4730 VE_INVALID_ARGUMENT, kTraceError, 4731 "SetRxAgcStatus() invalid Agc mode"); 4732 return -1; 4733 } 4734 4735 if (_rxAudioProcessingModulePtr->gain_control()->set_mode(agcMode) != 0) 4736 { 4737 _engineStatisticsPtr->SetLastError( 4738 VE_APM_ERROR, kTraceError, 4739 "SetRxAgcStatus() failed to set Agc mode"); 4740 return -1; 4741 } 4742 if (_rxAudioProcessingModulePtr->gain_control()->Enable(enable) != 0) 4743 { 4744 _engineStatisticsPtr->SetLastError( 4745 VE_APM_ERROR, kTraceError, 4746 "SetRxAgcStatus() failed to set Agc state"); 4747 return -1; 4748 } 4749 4750 _rxAgcIsEnabled = enable; 4751 _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 4752 4753 return 0; 4754} 4755 4756int 4757Channel::GetRxAgcStatus(bool& enabled, AgcModes& mode) 4758{ 4759 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4760 "Channel::GetRxAgcStatus(enable=?, mode=?)"); 4761 4762 bool enable = _rxAudioProcessingModulePtr->gain_control()->is_enabled(); 4763 GainControl::Mode agcMode = 4764 _rxAudioProcessingModulePtr->gain_control()->mode(); 4765 4766 enabled = enable; 4767 4768 switch (agcMode) 4769 { 4770 case GainControl::kFixedDigital: 4771 mode = kAgcFixedDigital; 4772 break; 4773 case GainControl::kAdaptiveDigital: 4774 mode = kAgcAdaptiveDigital; 4775 break; 4776 default: 4777 _engineStatisticsPtr->SetLastError( 4778 VE_APM_ERROR, kTraceError, 4779 "GetRxAgcStatus() invalid Agc mode"); 4780 return -1; 4781 } 4782 4783 return 0; 4784} 4785 4786int 4787Channel::SetRxAgcConfig(const AgcConfig config) 4788{ 4789 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4790 "Channel::SetRxAgcConfig()"); 4791 4792 if (_rxAudioProcessingModulePtr->gain_control()->set_target_level_dbfs( 4793 config.targetLeveldBOv) != 0) 4794 { 4795 _engineStatisticsPtr->SetLastError( 4796 VE_APM_ERROR, kTraceError, 4797 "SetRxAgcConfig() failed to set target peak |level|" 4798 "(or envelope) of the Agc"); 4799 return -1; 4800 } 4801 if (_rxAudioProcessingModulePtr->gain_control()->set_compression_gain_db( 4802 config.digitalCompressionGaindB) != 0) 4803 { 4804 _engineStatisticsPtr->SetLastError( 4805 VE_APM_ERROR, kTraceError, 4806 "SetRxAgcConfig() failed to set the range in |gain| the" 4807 " digital compression stage may apply"); 4808 return -1; 4809 } 4810 if (_rxAudioProcessingModulePtr->gain_control()->enable_limiter( 4811 config.limiterEnable) != 0) 4812 { 4813 _engineStatisticsPtr->SetLastError( 4814 VE_APM_ERROR, kTraceError, 4815 "SetRxAgcConfig() failed to set hard limiter to the signal"); 4816 return -1; 4817 } 4818 4819 return 0; 4820} 4821 4822int 4823Channel::GetRxAgcConfig(AgcConfig& config) 4824{ 4825 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4826 "Channel::GetRxAgcConfig(config=%?)"); 4827 4828 config.targetLeveldBOv = 4829 _rxAudioProcessingModulePtr->gain_control()->target_level_dbfs(); 4830 config.digitalCompressionGaindB = 4831 _rxAudioProcessingModulePtr->gain_control()->compression_gain_db(); 4832 config.limiterEnable = 4833 _rxAudioProcessingModulePtr->gain_control()->is_limiter_enabled(); 4834 4835 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4836 VoEId(_instanceId,_channelId), "GetRxAgcConfig() => " 4837 "targetLeveldBOv=%u, digitalCompressionGaindB=%u," 4838 " limiterEnable=%d", 4839 config.targetLeveldBOv, 4840 config.digitalCompressionGaindB, 4841 config.limiterEnable); 4842 4843 return 0; 4844} 4845 4846#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC 4847 4848#ifdef WEBRTC_VOICE_ENGINE_NR 4849 4850int 4851Channel::SetRxNsStatus(const bool enable, const NsModes mode) 4852{ 4853 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4854 "Channel::SetRxNsStatus(enable=%d, mode=%d)", 4855 (int)enable, (int)mode); 4856 4857 NoiseSuppression::Level nsLevel( 4858 (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE); 4859 switch (mode) 4860 { 4861 4862 case kNsDefault: 4863 nsLevel = (NoiseSuppression::Level) 4864 WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE; 4865 break; 4866 case kNsUnchanged: 4867 nsLevel = _rxAudioProcessingModulePtr->noise_suppression()->level(); 4868 break; 4869 case kNsConference: 4870 nsLevel = NoiseSuppression::kHigh; 4871 break; 4872 case kNsLowSuppression: 4873 nsLevel = NoiseSuppression::kLow; 4874 break; 4875 case kNsModerateSuppression: 4876 nsLevel = NoiseSuppression::kModerate; 4877 break; 4878 case kNsHighSuppression: 4879 nsLevel = NoiseSuppression::kHigh; 4880 break; 4881 case kNsVeryHighSuppression: 4882 nsLevel = NoiseSuppression::kVeryHigh; 4883 break; 4884 } 4885 4886 if (_rxAudioProcessingModulePtr->noise_suppression()->set_level(nsLevel) 4887 != 0) 4888 { 4889 _engineStatisticsPtr->SetLastError( 4890 VE_APM_ERROR, kTraceError, 4891 "SetRxAgcStatus() failed to set Ns level"); 4892 return -1; 4893 } 4894 if (_rxAudioProcessingModulePtr->noise_suppression()->Enable(enable) != 0) 4895 { 4896 _engineStatisticsPtr->SetLastError( 4897 VE_APM_ERROR, kTraceError, 4898 "SetRxAgcStatus() failed to set Agc state"); 4899 return -1; 4900 } 4901 4902 _rxNsIsEnabled = enable; 4903 _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 4904 4905 return 0; 4906} 4907 4908int 4909Channel::GetRxNsStatus(bool& enabled, NsModes& mode) 4910{ 4911 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4912 "Channel::GetRxNsStatus(enable=?, mode=?)"); 4913 4914 bool enable = 4915 _rxAudioProcessingModulePtr->noise_suppression()->is_enabled(); 4916 NoiseSuppression::Level ncLevel = 4917 _rxAudioProcessingModulePtr->noise_suppression()->level(); 4918 4919 enabled = enable; 4920 4921 switch (ncLevel) 4922 { 4923 case NoiseSuppression::kLow: 4924 mode = kNsLowSuppression; 4925 break; 4926 case NoiseSuppression::kModerate: 4927 mode = kNsModerateSuppression; 4928 break; 4929 case NoiseSuppression::kHigh: 4930 mode = kNsHighSuppression; 4931 break; 4932 case NoiseSuppression::kVeryHigh: 4933 mode = kNsVeryHighSuppression; 4934 break; 4935 } 4936 4937 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4938 VoEId(_instanceId,_channelId), 4939 "GetRxNsStatus() => enabled=%d, mode=%d", enabled, mode); 4940 return 0; 4941} 4942 4943#endif // #ifdef WEBRTC_VOICE_ENGINE_NR 4944 4945int 4946Channel::RegisterRTPObserver(VoERTPObserver& observer) 4947{ 4948 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4949 "Channel::RegisterRTPObserver()"); 4950 CriticalSectionScoped cs(&_callbackCritSect); 4951 4952 if (_rtpObserverPtr) 4953 { 4954 _engineStatisticsPtr->SetLastError( 4955 VE_INVALID_OPERATION, kTraceError, 4956 "RegisterRTPObserver() observer already enabled"); 4957 return -1; 4958 } 4959 4960 _rtpObserverPtr = &observer; 4961 _rtpObserver = true; 4962 4963 return 0; 4964} 4965 4966int 4967Channel::DeRegisterRTPObserver() 4968{ 4969 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4970 "Channel::DeRegisterRTPObserver()"); 4971 CriticalSectionScoped cs(&_callbackCritSect); 4972 4973 if (!_rtpObserverPtr) 4974 { 4975 _engineStatisticsPtr->SetLastError( 4976 VE_INVALID_OPERATION, kTraceWarning, 4977 "DeRegisterRTPObserver() observer already disabled"); 4978 return 0; 4979 } 4980 4981 _rtpObserver = false; 4982 _rtpObserverPtr = NULL; 4983 4984 return 0; 4985} 4986 4987int 4988Channel::RegisterRTCPObserver(VoERTCPObserver& observer) 4989{ 4990 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4991 "Channel::RegisterRTCPObserver()"); 4992 CriticalSectionScoped cs(&_callbackCritSect); 4993 4994 if (_rtcpObserverPtr) 4995 { 4996 _engineStatisticsPtr->SetLastError( 4997 VE_INVALID_OPERATION, kTraceError, 4998 "RegisterRTCPObserver() observer already enabled"); 4999 return -1; 5000 } 5001 5002 _rtcpObserverPtr = &observer; 5003 _rtcpObserver = true; 5004 5005 return 0; 5006} 5007 5008int 5009Channel::DeRegisterRTCPObserver() 5010{ 5011 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5012 "Channel::DeRegisterRTCPObserver()"); 5013 CriticalSectionScoped cs(&_callbackCritSect); 5014 5015 if (!_rtcpObserverPtr) 5016 { 5017 _engineStatisticsPtr->SetLastError( 5018 VE_INVALID_OPERATION, kTraceWarning, 5019 "DeRegisterRTCPObserver() observer already disabled"); 5020 return 0; 5021 } 5022 5023 _rtcpObserver = false; 5024 _rtcpObserverPtr = NULL; 5025 5026 return 0; 5027} 5028 5029int 5030Channel::SetLocalSSRC(unsigned int ssrc) 5031{ 5032 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5033 "Channel::SetLocalSSRC()"); 5034 if (_sending) 5035 { 5036 _engineStatisticsPtr->SetLastError( 5037 VE_ALREADY_SENDING, kTraceError, 5038 "SetLocalSSRC() already sending"); 5039 return -1; 5040 } 5041 if (_rtpRtcpModule->SetSSRC(ssrc) != 0) 5042 { 5043 _engineStatisticsPtr->SetLastError( 5044 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5045 "SetLocalSSRC() failed to set SSRC"); 5046 return -1; 5047 } 5048 return 0; 5049} 5050 5051int 5052Channel::GetLocalSSRC(unsigned int& ssrc) 5053{ 5054 ssrc = _rtpRtcpModule->SSRC(); 5055 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5056 VoEId(_instanceId,_channelId), 5057 "GetLocalSSRC() => ssrc=%lu", ssrc); 5058 return 0; 5059} 5060 5061int 5062Channel::GetRemoteSSRC(unsigned int& ssrc) 5063{ 5064 ssrc = _rtpRtcpModule->RemoteSSRC(); 5065 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5066 VoEId(_instanceId,_channelId), 5067 "GetRemoteSSRC() => ssrc=%lu", ssrc); 5068 return 0; 5069} 5070 5071int 5072Channel::GetRemoteCSRCs(unsigned int arrCSRC[15]) 5073{ 5074 if (arrCSRC == NULL) 5075 { 5076 _engineStatisticsPtr->SetLastError( 5077 VE_INVALID_ARGUMENT, kTraceError, 5078 "GetRemoteCSRCs() invalid array argument"); 5079 return -1; 5080 } 5081 WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]; 5082 WebRtc_Word32 CSRCs(0); 5083 CSRCs = _rtpRtcpModule->CSRCs(arrOfCSRC); 5084 if (CSRCs > 0) 5085 { 5086 memcpy(arrCSRC, arrOfCSRC, CSRCs * sizeof(WebRtc_UWord32)); 5087 for (int i = 0; i < (int) CSRCs; i++) 5088 { 5089 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5090 VoEId(_instanceId, _channelId), 5091 "GetRemoteCSRCs() => arrCSRC[%d]=%lu", i, arrCSRC[i]); 5092 } 5093 } else 5094 { 5095 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5096 VoEId(_instanceId, _channelId), 5097 "GetRemoteCSRCs() => list is empty!"); 5098 } 5099 return CSRCs; 5100} 5101 5102int 5103Channel::SetRTPAudioLevelIndicationStatus(bool enable, unsigned char ID) 5104{ 5105 if (_rtpAudioProc.get() == NULL) 5106 { 5107 _rtpAudioProc.reset(AudioProcessing::Create(VoEModuleId(_instanceId, 5108 _channelId))); 5109 if (_rtpAudioProc.get() == NULL) 5110 { 5111 _engineStatisticsPtr->SetLastError(VE_NO_MEMORY, kTraceCritical, 5112 "Failed to create AudioProcessing"); 5113 return -1; 5114 } 5115 } 5116 5117 if (_rtpAudioProc->level_estimator()->Enable(enable) != 5118 AudioProcessing::kNoError) 5119 { 5120 _engineStatisticsPtr->SetLastError(VE_APM_ERROR, kTraceWarning, 5121 "Failed to enable AudioProcessing::level_estimator()"); 5122 } 5123 5124 _includeAudioLevelIndication = enable; 5125 return _rtpRtcpModule->SetRTPAudioLevelIndicationStatus(enable, ID); 5126} 5127int 5128Channel::GetRTPAudioLevelIndicationStatus(bool& enabled, unsigned char& ID) 5129{ 5130 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5131 VoEId(_instanceId,_channelId), 5132 "GetRTPAudioLevelIndicationStatus() => enabled=%d, ID=%u", 5133 enabled, ID); 5134 return _rtpRtcpModule->GetRTPAudioLevelIndicationStatus(enabled, ID); 5135} 5136 5137int 5138Channel::SetRTCPStatus(bool enable) 5139{ 5140 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5141 "Channel::SetRTCPStatus()"); 5142 if (_rtpRtcpModule->SetRTCPStatus(enable ? 5143 kRtcpCompound : kRtcpOff) != 0) 5144 { 5145 _engineStatisticsPtr->SetLastError( 5146 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5147 "SetRTCPStatus() failed to set RTCP status"); 5148 return -1; 5149 } 5150 return 0; 5151} 5152 5153int 5154Channel::GetRTCPStatus(bool& enabled) 5155{ 5156 RTCPMethod method = _rtpRtcpModule->RTCP(); 5157 enabled = (method != kRtcpOff); 5158 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5159 VoEId(_instanceId,_channelId), 5160 "GetRTCPStatus() => enabled=%d", enabled); 5161 return 0; 5162} 5163 5164int 5165Channel::SetRTCP_CNAME(const char cName[256]) 5166{ 5167 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5168 "Channel::SetRTCP_CNAME()"); 5169 if (_rtpRtcpModule->SetCNAME(cName) != 0) 5170 { 5171 _engineStatisticsPtr->SetLastError( 5172 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5173 "SetRTCP_CNAME() failed to set RTCP CNAME"); 5174 return -1; 5175 } 5176 return 0; 5177} 5178 5179int 5180Channel::GetRTCP_CNAME(char cName[256]) 5181{ 5182 if (_rtpRtcpModule->CNAME(cName) != 0) 5183 { 5184 _engineStatisticsPtr->SetLastError( 5185 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5186 "GetRTCP_CNAME() failed to retrieve RTCP CNAME"); 5187 return -1; 5188 } 5189 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5190 VoEId(_instanceId, _channelId), 5191 "GetRTCP_CNAME() => cName=%s", cName); 5192 return 0; 5193} 5194 5195int 5196Channel::GetRemoteRTCP_CNAME(char cName[256]) 5197{ 5198 if (cName == NULL) 5199 { 5200 _engineStatisticsPtr->SetLastError( 5201 VE_INVALID_ARGUMENT, kTraceError, 5202 "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); 5203 return -1; 5204 } 5205 char cname[RTCP_CNAME_SIZE]; 5206 const WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5207 if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) 5208 { 5209 _engineStatisticsPtr->SetLastError( 5210 VE_CANNOT_RETRIEVE_CNAME, kTraceError, 5211 "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); 5212 return -1; 5213 } 5214 strcpy(cName, cname); 5215 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5216 VoEId(_instanceId, _channelId), 5217 "GetRemoteRTCP_CNAME() => cName=%s", cName); 5218 return 0; 5219} 5220 5221int 5222Channel::GetRemoteRTCPData( 5223 unsigned int& NTPHigh, 5224 unsigned int& NTPLow, 5225 unsigned int& timestamp, 5226 unsigned int& playoutTimestamp, 5227 unsigned int* jitter, 5228 unsigned short* fractionLost) 5229{ 5230 // --- Information from sender info in received Sender Reports 5231 5232 RTCPSenderInfo senderInfo; 5233 if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) 5234 { 5235 _engineStatisticsPtr->SetLastError( 5236 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5237 "GetRemoteRTCPData() failed to retrieve sender info for remote " 5238 "side"); 5239 return -1; 5240 } 5241 5242 // We only utilize 12 out of 20 bytes in the sender info (ignores packet 5243 // and octet count) 5244 NTPHigh = senderInfo.NTPseconds; 5245 NTPLow = senderInfo.NTPfraction; 5246 timestamp = senderInfo.RTPtimeStamp; 5247 5248 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5249 VoEId(_instanceId, _channelId), 5250 "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " 5251 "timestamp=%lu", 5252 NTPHigh, NTPLow, timestamp); 5253 5254 // --- Locally derived information 5255 5256 // This value is updated on each incoming RTCP packet (0 when no packet 5257 // has been received) 5258 playoutTimestamp = _playoutTimeStampRTCP; 5259 5260 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5261 VoEId(_instanceId, _channelId), 5262 "GetRemoteRTCPData() => playoutTimestamp=%lu", 5263 _playoutTimeStampRTCP); 5264 5265 if (NULL != jitter || NULL != fractionLost) 5266 { 5267 // Get all RTCP receiver report blocks that have been received on this 5268 // channel. If we receive RTP packets from a remote source we know the 5269 // remote SSRC and use the report block from him. 5270 // Otherwise use the first report block. 5271 std::vector<RTCPReportBlock> remote_stats; 5272 if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || 5273 remote_stats.empty()) { 5274 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5275 VoEId(_instanceId, _channelId), 5276 "GetRemoteRTCPData() failed to measure statistics due" 5277 " to lack of received RTP and/or RTCP packets"); 5278 return -1; 5279 } 5280 5281 WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5282 std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin(); 5283 for (; it != remote_stats.end(); ++it) { 5284 if (it->remoteSSRC == remoteSSRC) 5285 break; 5286 } 5287 5288 if (it == remote_stats.end()) { 5289 // If we have not received any RTCP packets from this SSRC it probably 5290 // means that we have not received any RTP packets. 5291 // Use the first received report block instead. 5292 it = remote_stats.begin(); 5293 remoteSSRC = it->remoteSSRC; 5294 } 5295 5296 if (jitter) { 5297 *jitter = it->jitter; 5298 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5299 VoEId(_instanceId, _channelId), 5300 "GetRemoteRTCPData() => jitter = %lu", *jitter); 5301 } 5302 5303 if (fractionLost) { 5304 *fractionLost = it->fractionLost; 5305 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5306 VoEId(_instanceId, _channelId), 5307 "GetRemoteRTCPData() => fractionLost = %lu", 5308 *fractionLost); 5309 } 5310 } 5311 return 0; 5312} 5313 5314int 5315Channel::SendApplicationDefinedRTCPPacket(const unsigned char subType, 5316 unsigned int name, 5317 const char* data, 5318 unsigned short dataLengthInBytes) 5319{ 5320 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5321 "Channel::SendApplicationDefinedRTCPPacket()"); 5322 if (!_sending) 5323 { 5324 _engineStatisticsPtr->SetLastError( 5325 VE_NOT_SENDING, kTraceError, 5326 "SendApplicationDefinedRTCPPacket() not sending"); 5327 return -1; 5328 } 5329 if (NULL == data) 5330 { 5331 _engineStatisticsPtr->SetLastError( 5332 VE_INVALID_ARGUMENT, kTraceError, 5333 "SendApplicationDefinedRTCPPacket() invalid data value"); 5334 return -1; 5335 } 5336 if (dataLengthInBytes % 4 != 0) 5337 { 5338 _engineStatisticsPtr->SetLastError( 5339 VE_INVALID_ARGUMENT, kTraceError, 5340 "SendApplicationDefinedRTCPPacket() invalid length value"); 5341 return -1; 5342 } 5343 RTCPMethod status = _rtpRtcpModule->RTCP(); 5344 if (status == kRtcpOff) 5345 { 5346 _engineStatisticsPtr->SetLastError( 5347 VE_RTCP_ERROR, kTraceError, 5348 "SendApplicationDefinedRTCPPacket() RTCP is disabled"); 5349 return -1; 5350 } 5351 5352 // Create and schedule the RTCP APP packet for transmission 5353 if (_rtpRtcpModule->SetRTCPApplicationSpecificData( 5354 subType, 5355 name, 5356 (const unsigned char*) data, 5357 dataLengthInBytes) != 0) 5358 { 5359 _engineStatisticsPtr->SetLastError( 5360 VE_SEND_ERROR, kTraceError, 5361 "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); 5362 return -1; 5363 } 5364 return 0; 5365} 5366 5367int 5368Channel::GetRTPStatistics( 5369 unsigned int& averageJitterMs, 5370 unsigned int& maxJitterMs, 5371 unsigned int& discardedPackets) 5372{ 5373 WebRtc_UWord8 fraction_lost(0); 5374 WebRtc_UWord32 cum_lost(0); 5375 WebRtc_UWord32 ext_max(0); 5376 WebRtc_UWord32 jitter(0); 5377 WebRtc_UWord32 max_jitter(0); 5378 5379 // The jitter statistics is updated for each received RTP packet and is 5380 // based on received packets. 5381 if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 5382 &cum_lost, 5383 &ext_max, 5384 &jitter, 5385 &max_jitter) != 0) 5386 { 5387 _engineStatisticsPtr->SetLastError( 5388 VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 5389 "GetRTPStatistics() failed to read RTP statistics from the " 5390 "RTP/RTCP module"); 5391 } 5392 5393 const WebRtc_Word32 playoutFrequency = 5394 _audioCodingModule.PlayoutFrequency(); 5395 if (playoutFrequency > 0) 5396 { 5397 // Scale RTP statistics given the current playout frequency 5398 maxJitterMs = max_jitter / (playoutFrequency / 1000); 5399 averageJitterMs = jitter / (playoutFrequency / 1000); 5400 } 5401 5402 discardedPackets = _numberOfDiscardedPackets; 5403 5404 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5405 VoEId(_instanceId, _channelId), 5406 "GetRTPStatistics() => averageJitterMs = %lu, maxJitterMs = %lu," 5407 " discardedPackets = %lu)", 5408 averageJitterMs, maxJitterMs, discardedPackets); 5409 return 0; 5410} 5411 5412int Channel::GetRemoteRTCPSenderInfo(SenderInfo* sender_info) { 5413 if (sender_info == NULL) { 5414 _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 5415 "GetRemoteRTCPSenderInfo() invalid sender_info."); 5416 return -1; 5417 } 5418 5419 // Get the sender info from the latest received RTCP Sender Report. 5420 RTCPSenderInfo rtcp_sender_info; 5421 if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_sender_info) != 0) { 5422 _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5423 "GetRemoteRTCPSenderInfo() failed to read RTCP SR sender info."); 5424 return -1; 5425 } 5426 5427 sender_info->NTP_timestamp_high = rtcp_sender_info.NTPseconds; 5428 sender_info->NTP_timestamp_low = rtcp_sender_info.NTPfraction; 5429 sender_info->RTP_timestamp = rtcp_sender_info.RTPtimeStamp; 5430 sender_info->sender_packet_count = rtcp_sender_info.sendPacketCount; 5431 sender_info->sender_octet_count = rtcp_sender_info.sendOctetCount; 5432 return 0; 5433} 5434 5435int Channel::GetRemoteRTCPReportBlocks( 5436 std::vector<ReportBlock>* report_blocks) { 5437 if (report_blocks == NULL) { 5438 _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 5439 "GetRemoteRTCPReportBlock()s invalid report_blocks."); 5440 return -1; 5441 } 5442 5443 // Get the report blocks from the latest received RTCP Sender or Receiver 5444 // Report. Each element in the vector contains the sender's SSRC and a 5445 // report block according to RFC 3550. 5446 std::vector<RTCPReportBlock> rtcp_report_blocks; 5447 if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) { 5448 _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5449 "GetRemoteRTCPReportBlocks() failed to read RTCP SR/RR report block."); 5450 return -1; 5451 } 5452 5453 if (rtcp_report_blocks.empty()) 5454 return 0; 5455 5456 std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin(); 5457 for (; it != rtcp_report_blocks.end(); ++it) { 5458 ReportBlock report_block; 5459 report_block.sender_SSRC = it->remoteSSRC; 5460 report_block.source_SSRC = it->sourceSSRC; 5461 report_block.fraction_lost = it->fractionLost; 5462 report_block.cumulative_num_packets_lost = it->cumulativeLost; 5463 report_block.extended_highest_sequence_number = it->extendedHighSeqNum; 5464 report_block.interarrival_jitter = it->jitter; 5465 report_block.last_SR_timestamp = it->lastSR; 5466 report_block.delay_since_last_SR = it->delaySinceLastSR; 5467 report_blocks->push_back(report_block); 5468 } 5469 return 0; 5470} 5471 5472int 5473Channel::GetRTPStatistics(CallStatistics& stats) 5474{ 5475 WebRtc_UWord8 fraction_lost(0); 5476 WebRtc_UWord32 cum_lost(0); 5477 WebRtc_UWord32 ext_max(0); 5478 WebRtc_UWord32 jitter(0); 5479 WebRtc_UWord32 max_jitter(0); 5480 5481 // --- Part one of the final structure (four values) 5482 5483 // The jitter statistics is updated for each received RTP packet and is 5484 // based on received packets. 5485 if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 5486 &cum_lost, 5487 &ext_max, 5488 &jitter, 5489 &max_jitter) != 0) 5490 { 5491 _engineStatisticsPtr->SetLastError( 5492 VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 5493 "GetRTPStatistics() failed to read RTP statistics from the " 5494 "RTP/RTCP module"); 5495 } 5496 5497 stats.fractionLost = fraction_lost; 5498 stats.cumulativeLost = cum_lost; 5499 stats.extendedMax = ext_max; 5500 stats.jitterSamples = jitter; 5501 5502 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5503 VoEId(_instanceId, _channelId), 5504 "GetRTPStatistics() => fractionLost=%lu, cumulativeLost=%lu," 5505 " extendedMax=%lu, jitterSamples=%li)", 5506 stats.fractionLost, stats.cumulativeLost, stats.extendedMax, 5507 stats.jitterSamples); 5508 5509 // --- Part two of the final structure (one value) 5510 5511 WebRtc_UWord16 RTT(0); 5512 RTCPMethod method = _rtpRtcpModule->RTCP(); 5513 if (method == kRtcpOff) 5514 { 5515 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5516 VoEId(_instanceId, _channelId), 5517 "GetRTPStatistics() RTCP is disabled => valid RTT " 5518 "measurements cannot be retrieved"); 5519 } else 5520 { 5521 // The remote SSRC will be zero if no RTP packet has been received. 5522 WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5523 if (remoteSSRC > 0) 5524 { 5525 WebRtc_UWord16 avgRTT(0); 5526 WebRtc_UWord16 maxRTT(0); 5527 WebRtc_UWord16 minRTT(0); 5528 5529 if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT, &maxRTT) 5530 != 0) 5531 { 5532 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5533 VoEId(_instanceId, _channelId), 5534 "GetRTPStatistics() failed to retrieve RTT from " 5535 "the RTP/RTCP module"); 5536 } 5537 } else 5538 { 5539 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5540 VoEId(_instanceId, _channelId), 5541 "GetRTPStatistics() failed to measure RTT since no " 5542 "RTP packets have been received yet"); 5543 } 5544 } 5545 5546 stats.rttMs = static_cast<int> (RTT); 5547 5548 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5549 VoEId(_instanceId, _channelId), 5550 "GetRTPStatistics() => rttMs=%d", stats.rttMs); 5551 5552 // --- Part three of the final structure (four values) 5553 5554 WebRtc_UWord32 bytesSent(0); 5555 WebRtc_UWord32 packetsSent(0); 5556 WebRtc_UWord32 bytesReceived(0); 5557 WebRtc_UWord32 packetsReceived(0); 5558 5559 if (_rtpRtcpModule->DataCountersRTP(&bytesSent, 5560 &packetsSent, 5561 &bytesReceived, 5562 &packetsReceived) != 0) 5563 { 5564 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5565 VoEId(_instanceId, _channelId), 5566 "GetRTPStatistics() failed to retrieve RTP datacounters =>" 5567 " output will not be complete"); 5568 } 5569 5570 stats.bytesSent = bytesSent; 5571 stats.packetsSent = packetsSent; 5572 stats.bytesReceived = bytesReceived; 5573 stats.packetsReceived = packetsReceived; 5574 5575 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5576 VoEId(_instanceId, _channelId), 5577 "GetRTPStatistics() => bytesSent=%d, packetsSent=%d," 5578 " bytesReceived=%d, packetsReceived=%d)", 5579 stats.bytesSent, stats.packetsSent, stats.bytesReceived, 5580 stats.packetsReceived); 5581 5582 return 0; 5583} 5584 5585int Channel::SetFECStatus(bool enable, int redPayloadtype) { 5586 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5587 "Channel::SetFECStatus()"); 5588 5589 if (SetRedPayloadType(redPayloadtype) < 0) { 5590 _engineStatisticsPtr->SetLastError( 5591 VE_CODEC_ERROR, kTraceError, 5592 "SetSecondarySendCodec() Failed to register RED ACM"); 5593 return -1; 5594 } 5595 5596 if (_audioCodingModule.SetFECStatus(enable) != 0) { 5597 _engineStatisticsPtr->SetLastError( 5598 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 5599 "SetFECStatus() failed to set FEC state in the ACM"); 5600 return -1; 5601 } 5602 return 0; 5603} 5604 5605int 5606Channel::GetFECStatus(bool& enabled, int& redPayloadtype) 5607{ 5608 enabled = _audioCodingModule.FECStatus(); 5609 if (enabled) 5610 { 5611 WebRtc_Word8 payloadType(0); 5612 if (_rtpRtcpModule->SendREDPayloadType(payloadType) != 0) 5613 { 5614 _engineStatisticsPtr->SetLastError( 5615 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5616 "GetFECStatus() failed to retrieve RED PT from RTP/RTCP " 5617 "module"); 5618 return -1; 5619 } 5620 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5621 VoEId(_instanceId, _channelId), 5622 "GetFECStatus() => enabled=%d, redPayloadtype=%d", 5623 enabled, redPayloadtype); 5624 return 0; 5625 } 5626 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5627 VoEId(_instanceId, _channelId), 5628 "GetFECStatus() => enabled=%d", enabled); 5629 return 0; 5630} 5631 5632int 5633Channel::StartRTPDump(const char fileNameUTF8[1024], 5634 RTPDirections direction) 5635{ 5636 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5637 "Channel::StartRTPDump()"); 5638 if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 5639 { 5640 _engineStatisticsPtr->SetLastError( 5641 VE_INVALID_ARGUMENT, kTraceError, 5642 "StartRTPDump() invalid RTP direction"); 5643 return -1; 5644 } 5645 RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5646 &_rtpDumpIn : &_rtpDumpOut; 5647 if (rtpDumpPtr == NULL) 5648 { 5649 assert(false); 5650 return -1; 5651 } 5652 if (rtpDumpPtr->IsActive()) 5653 { 5654 rtpDumpPtr->Stop(); 5655 } 5656 if (rtpDumpPtr->Start(fileNameUTF8) != 0) 5657 { 5658 _engineStatisticsPtr->SetLastError( 5659 VE_BAD_FILE, kTraceError, 5660 "StartRTPDump() failed to create file"); 5661 return -1; 5662 } 5663 return 0; 5664} 5665 5666int 5667Channel::StopRTPDump(RTPDirections direction) 5668{ 5669 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5670 "Channel::StopRTPDump()"); 5671 if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 5672 { 5673 _engineStatisticsPtr->SetLastError( 5674 VE_INVALID_ARGUMENT, kTraceError, 5675 "StopRTPDump() invalid RTP direction"); 5676 return -1; 5677 } 5678 RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5679 &_rtpDumpIn : &_rtpDumpOut; 5680 if (rtpDumpPtr == NULL) 5681 { 5682 assert(false); 5683 return -1; 5684 } 5685 if (!rtpDumpPtr->IsActive()) 5686 { 5687 return 0; 5688 } 5689 return rtpDumpPtr->Stop(); 5690} 5691 5692bool 5693Channel::RTPDumpIsActive(RTPDirections direction) 5694{ 5695 if ((direction != kRtpIncoming) && 5696 (direction != kRtpOutgoing)) 5697 { 5698 _engineStatisticsPtr->SetLastError( 5699 VE_INVALID_ARGUMENT, kTraceError, 5700 "RTPDumpIsActive() invalid RTP direction"); 5701 return false; 5702 } 5703 RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5704 &_rtpDumpIn : &_rtpDumpOut; 5705 return rtpDumpPtr->IsActive(); 5706} 5707 5708int 5709Channel::InsertExtraRTPPacket(unsigned char payloadType, 5710 bool markerBit, 5711 const char* payloadData, 5712 unsigned short payloadSize) 5713{ 5714 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5715 "Channel::InsertExtraRTPPacket()"); 5716 if (payloadType > 127) 5717 { 5718 _engineStatisticsPtr->SetLastError( 5719 VE_INVALID_PLTYPE, kTraceError, 5720 "InsertExtraRTPPacket() invalid payload type"); 5721 return -1; 5722 } 5723 if (payloadData == NULL) 5724 { 5725 _engineStatisticsPtr->SetLastError( 5726 VE_INVALID_ARGUMENT, kTraceError, 5727 "InsertExtraRTPPacket() invalid payload data"); 5728 return -1; 5729 } 5730 if (payloadSize > _rtpRtcpModule->MaxDataPayloadLength()) 5731 { 5732 _engineStatisticsPtr->SetLastError( 5733 VE_INVALID_ARGUMENT, kTraceError, 5734 "InsertExtraRTPPacket() invalid payload size"); 5735 return -1; 5736 } 5737 if (!_sending) 5738 { 5739 _engineStatisticsPtr->SetLastError( 5740 VE_NOT_SENDING, kTraceError, 5741 "InsertExtraRTPPacket() not sending"); 5742 return -1; 5743 } 5744 5745 // Create extra RTP packet by calling RtpRtcp::SendOutgoingData(). 5746 // Transport::SendPacket() will be called by the module when the RTP packet 5747 // is created. 5748 // The call to SendOutgoingData() does *not* modify the timestamp and 5749 // payloadtype to ensure that the RTP module generates a valid RTP packet 5750 // (user might utilize a non-registered payload type). 5751 // The marker bit and payload type will be replaced just before the actual 5752 // transmission, i.e., the actual modification is done *after* the RTP 5753 // module has delivered its RTP packet back to the VoE. 5754 // We will use the stored values above when the packet is modified 5755 // (see Channel::SendPacket()). 5756 5757 _extraPayloadType = payloadType; 5758 _extraMarkerBit = markerBit; 5759 _insertExtraRTPPacket = true; 5760 5761 if (_rtpRtcpModule->SendOutgoingData(kAudioFrameSpeech, 5762 _lastPayloadType, 5763 _lastLocalTimeStamp, 5764 // Leaving the time when this frame was 5765 // received from the capture device as 5766 // undefined for voice for now. 5767 -1, 5768 (const WebRtc_UWord8*) payloadData, 5769 payloadSize) != 0) 5770 { 5771 _engineStatisticsPtr->SetLastError( 5772 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5773 "InsertExtraRTPPacket() failed to send extra RTP packet"); 5774 return -1; 5775 } 5776 5777 return 0; 5778} 5779 5780WebRtc_UWord32 5781Channel::Demultiplex(const AudioFrame& audioFrame) 5782{ 5783 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5784 "Channel::Demultiplex()"); 5785 _audioFrame = audioFrame; 5786 _audioFrame.id_ = _channelId; 5787 return 0; 5788} 5789 5790WebRtc_UWord32 5791Channel::PrepareEncodeAndSend(int mixingFrequency) 5792{ 5793 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5794 "Channel::PrepareEncodeAndSend()"); 5795 5796 if (_audioFrame.samples_per_channel_ == 0) 5797 { 5798 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 5799 "Channel::PrepareEncodeAndSend() invalid audio frame"); 5800 return -1; 5801 } 5802 5803 if (_inputFilePlaying) 5804 { 5805 MixOrReplaceAudioWithFile(mixingFrequency); 5806 } 5807 5808 if (_mute) 5809 { 5810 AudioFrameOperations::Mute(_audioFrame); 5811 } 5812 5813 if (_inputExternalMedia) 5814 { 5815 CriticalSectionScoped cs(&_callbackCritSect); 5816 const bool isStereo = (_audioFrame.num_channels_ == 2); 5817 if (_inputExternalMediaCallbackPtr) 5818 { 5819 _inputExternalMediaCallbackPtr->Process( 5820 _channelId, 5821 kRecordingPerChannel, 5822 (WebRtc_Word16*)_audioFrame.data_, 5823 _audioFrame.samples_per_channel_, 5824 _audioFrame.sample_rate_hz_, 5825 isStereo); 5826 } 5827 } 5828 5829 InsertInbandDtmfTone(); 5830 5831 if (_includeAudioLevelIndication) 5832 { 5833 assert(_rtpAudioProc.get() != NULL); 5834 5835 // Check if settings need to be updated. 5836 if (_rtpAudioProc->sample_rate_hz() != _audioFrame.sample_rate_hz_) 5837 { 5838 if (_rtpAudioProc->set_sample_rate_hz(_audioFrame.sample_rate_hz_) != 5839 AudioProcessing::kNoError) 5840 { 5841 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5842 VoEId(_instanceId, _channelId), 5843 "Error setting AudioProcessing sample rate"); 5844 return -1; 5845 } 5846 } 5847 5848 if (_rtpAudioProc->num_input_channels() != _audioFrame.num_channels_) 5849 { 5850 if (_rtpAudioProc->set_num_channels(_audioFrame.num_channels_, 5851 _audioFrame.num_channels_) 5852 != AudioProcessing::kNoError) 5853 { 5854 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5855 VoEId(_instanceId, _channelId), 5856 "Error setting AudioProcessing channels"); 5857 return -1; 5858 } 5859 } 5860 5861 // Performs level analysis only; does not affect the signal. 5862 _rtpAudioProc->ProcessStream(&_audioFrame); 5863 } 5864 5865 return 0; 5866} 5867 5868WebRtc_UWord32 5869Channel::EncodeAndSend() 5870{ 5871 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5872 "Channel::EncodeAndSend()"); 5873 5874 assert(_audioFrame.num_channels_ <= 2); 5875 if (_audioFrame.samples_per_channel_ == 0) 5876 { 5877 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 5878 "Channel::EncodeAndSend() invalid audio frame"); 5879 return -1; 5880 } 5881 5882 _audioFrame.id_ = _channelId; 5883 5884 // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. 5885 5886 // The ACM resamples internally. 5887 _audioFrame.timestamp_ = _timeStamp; 5888 if (_audioCodingModule.Add10MsData((AudioFrame&)_audioFrame) != 0) 5889 { 5890 WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 5891 "Channel::EncodeAndSend() ACM encoding failed"); 5892 return -1; 5893 } 5894 5895 _timeStamp += _audioFrame.samples_per_channel_; 5896 5897 // --- Encode if complete frame is ready 5898 5899 // This call will trigger AudioPacketizationCallback::SendData if encoding 5900 // is done and payload is ready for packetization and transmission. 5901 return _audioCodingModule.Process(); 5902} 5903 5904int Channel::RegisterExternalMediaProcessing( 5905 ProcessingTypes type, 5906 VoEMediaProcess& processObject) 5907{ 5908 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5909 "Channel::RegisterExternalMediaProcessing()"); 5910 5911 CriticalSectionScoped cs(&_callbackCritSect); 5912 5913 if (kPlaybackPerChannel == type) 5914 { 5915 if (_outputExternalMediaCallbackPtr) 5916 { 5917 _engineStatisticsPtr->SetLastError( 5918 VE_INVALID_OPERATION, kTraceError, 5919 "Channel::RegisterExternalMediaProcessing() " 5920 "output external media already enabled"); 5921 return -1; 5922 } 5923 _outputExternalMediaCallbackPtr = &processObject; 5924 _outputExternalMedia = true; 5925 } 5926 else if (kRecordingPerChannel == type) 5927 { 5928 if (_inputExternalMediaCallbackPtr) 5929 { 5930 _engineStatisticsPtr->SetLastError( 5931 VE_INVALID_OPERATION, kTraceError, 5932 "Channel::RegisterExternalMediaProcessing() " 5933 "output external media already enabled"); 5934 return -1; 5935 } 5936 _inputExternalMediaCallbackPtr = &processObject; 5937 _inputExternalMedia = true; 5938 } 5939 return 0; 5940} 5941 5942int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) 5943{ 5944 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5945 "Channel::DeRegisterExternalMediaProcessing()"); 5946 5947 CriticalSectionScoped cs(&_callbackCritSect); 5948 5949 if (kPlaybackPerChannel == type) 5950 { 5951 if (!_outputExternalMediaCallbackPtr) 5952 { 5953 _engineStatisticsPtr->SetLastError( 5954 VE_INVALID_OPERATION, kTraceWarning, 5955 "Channel::DeRegisterExternalMediaProcessing() " 5956 "output external media already disabled"); 5957 return 0; 5958 } 5959 _outputExternalMedia = false; 5960 _outputExternalMediaCallbackPtr = NULL; 5961 } 5962 else if (kRecordingPerChannel == type) 5963 { 5964 if (!_inputExternalMediaCallbackPtr) 5965 { 5966 _engineStatisticsPtr->SetLastError( 5967 VE_INVALID_OPERATION, kTraceWarning, 5968 "Channel::DeRegisterExternalMediaProcessing() " 5969 "input external media already disabled"); 5970 return 0; 5971 } 5972 _inputExternalMedia = false; 5973 _inputExternalMediaCallbackPtr = NULL; 5974 } 5975 5976 return 0; 5977} 5978 5979int 5980Channel::ResetRTCPStatistics() 5981{ 5982 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5983 "Channel::ResetRTCPStatistics()"); 5984 WebRtc_UWord32 remoteSSRC(0); 5985 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5986 return _rtpRtcpModule->ResetRTT(remoteSSRC); 5987} 5988 5989int 5990Channel::GetRoundTripTimeSummary(StatVal& delaysMs) const 5991{ 5992 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5993 "Channel::GetRoundTripTimeSummary()"); 5994 // Override default module outputs for the case when RTCP is disabled. 5995 // This is done to ensure that we are backward compatible with the 5996 // VoiceEngine where we did not use RTP/RTCP module. 5997 if (!_rtpRtcpModule->RTCP()) 5998 { 5999 delaysMs.min = -1; 6000 delaysMs.max = -1; 6001 delaysMs.average = -1; 6002 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6003 "Channel::GetRoundTripTimeSummary() RTCP is disabled =>" 6004 " valid RTT measurements cannot be retrieved"); 6005 return 0; 6006 } 6007 6008 WebRtc_UWord32 remoteSSRC; 6009 WebRtc_UWord16 RTT; 6010 WebRtc_UWord16 avgRTT; 6011 WebRtc_UWord16 maxRTT; 6012 WebRtc_UWord16 minRTT; 6013 // The remote SSRC will be zero if no RTP packet has been received. 6014 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 6015 if (remoteSSRC == 0) 6016 { 6017 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6018 "Channel::GetRoundTripTimeSummary() unable to measure RTT" 6019 " since no RTP packet has been received yet"); 6020 } 6021 6022 // Retrieve RTT statistics from the RTP/RTCP module for the specified 6023 // channel and SSRC. The SSRC is required to parse out the correct source 6024 // in conference scenarios. 6025 if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT,&maxRTT) != 0) 6026 { 6027 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6028 "GetRoundTripTimeSummary unable to retrieve RTT values" 6029 " from the RTCP layer"); 6030 delaysMs.min = -1; delaysMs.max = -1; delaysMs.average = -1; 6031 } 6032 else 6033 { 6034 delaysMs.min = minRTT; 6035 delaysMs.max = maxRTT; 6036 delaysMs.average = avgRTT; 6037 } 6038 return 0; 6039} 6040 6041int 6042Channel::GetNetworkStatistics(NetworkStatistics& stats) 6043{ 6044 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6045 "Channel::GetNetworkStatistics()"); 6046 return _audioCodingModule.NetworkStatistics( 6047 (ACMNetworkStatistics &)stats); 6048} 6049 6050int 6051Channel::GetDelayEstimate(int& delayMs) const 6052{ 6053 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6054 "Channel::GetDelayEstimate()"); 6055 delayMs = (_averageDelayMs + 5) / 10 + _recPacketDelayMs; 6056 return 0; 6057} 6058 6059int 6060Channel::SetMinimumPlayoutDelay(int delayMs) 6061{ 6062 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6063 "Channel::SetMinimumPlayoutDelay()"); 6064 if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || 6065 (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) 6066 { 6067 _engineStatisticsPtr->SetLastError( 6068 VE_INVALID_ARGUMENT, kTraceError, 6069 "SetMinimumPlayoutDelay() invalid min delay"); 6070 return -1; 6071 } 6072 if (_audioCodingModule.SetMinimumPlayoutDelay(delayMs) != 0) 6073 { 6074 _engineStatisticsPtr->SetLastError( 6075 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6076 "SetMinimumPlayoutDelay() failed to set min playout delay"); 6077 return -1; 6078 } 6079 return 0; 6080} 6081 6082int 6083Channel::GetPlayoutTimestamp(unsigned int& timestamp) 6084{ 6085 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6086 "Channel::GetPlayoutTimestamp()"); 6087 WebRtc_UWord32 playoutTimestamp(0); 6088 if (GetPlayoutTimeStamp(playoutTimestamp) != 0) 6089 { 6090 _engineStatisticsPtr->SetLastError( 6091 VE_CANNOT_RETRIEVE_VALUE, kTraceError, 6092 "GetPlayoutTimestamp() failed to retrieve timestamp"); 6093 return -1; 6094 } 6095 timestamp = playoutTimestamp; 6096 WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 6097 VoEId(_instanceId,_channelId), 6098 "GetPlayoutTimestamp() => timestamp=%u", timestamp); 6099 return 0; 6100} 6101 6102int 6103Channel::SetInitTimestamp(unsigned int timestamp) 6104{ 6105 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6106 "Channel::SetInitTimestamp()"); 6107 if (_sending) 6108 { 6109 _engineStatisticsPtr->SetLastError( 6110 VE_SENDING, kTraceError, "SetInitTimestamp() already sending"); 6111 return -1; 6112 } 6113 if (_rtpRtcpModule->SetStartTimestamp(timestamp) != 0) 6114 { 6115 _engineStatisticsPtr->SetLastError( 6116 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 6117 "SetInitTimestamp() failed to set timestamp"); 6118 return -1; 6119 } 6120 return 0; 6121} 6122 6123int 6124Channel::SetInitSequenceNumber(short sequenceNumber) 6125{ 6126 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6127 "Channel::SetInitSequenceNumber()"); 6128 if (_sending) 6129 { 6130 _engineStatisticsPtr->SetLastError( 6131 VE_SENDING, kTraceError, 6132 "SetInitSequenceNumber() already sending"); 6133 return -1; 6134 } 6135 if (_rtpRtcpModule->SetSequenceNumber(sequenceNumber) != 0) 6136 { 6137 _engineStatisticsPtr->SetLastError( 6138 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 6139 "SetInitSequenceNumber() failed to set sequence number"); 6140 return -1; 6141 } 6142 return 0; 6143} 6144 6145int 6146Channel::GetRtpRtcp(RtpRtcp* &rtpRtcpModule) const 6147{ 6148 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6149 "Channel::GetRtpRtcp()"); 6150 rtpRtcpModule = _rtpRtcpModule.get(); 6151 return 0; 6152} 6153 6154// TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use 6155// a shared helper. 6156WebRtc_Word32 6157Channel::MixOrReplaceAudioWithFile(const int mixingFrequency) 6158{ 6159 scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]); 6160 int fileSamples(0); 6161 6162 { 6163 CriticalSectionScoped cs(&_fileCritSect); 6164 6165 if (_inputFilePlayerPtr == NULL) 6166 { 6167 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6168 VoEId(_instanceId, _channelId), 6169 "Channel::MixOrReplaceAudioWithFile() fileplayer" 6170 " doesnt exist"); 6171 return -1; 6172 } 6173 6174 if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 6175 fileSamples, 6176 mixingFrequency) == -1) 6177 { 6178 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6179 VoEId(_instanceId, _channelId), 6180 "Channel::MixOrReplaceAudioWithFile() file mixing " 6181 "failed"); 6182 return -1; 6183 } 6184 if (fileSamples == 0) 6185 { 6186 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6187 VoEId(_instanceId, _channelId), 6188 "Channel::MixOrReplaceAudioWithFile() file is ended"); 6189 return 0; 6190 } 6191 } 6192 6193 assert(_audioFrame.samples_per_channel_ == fileSamples); 6194 6195 if (_mixFileWithMicrophone) 6196 { 6197 // Currently file stream is always mono. 6198 // TODO(xians): Change the code when FilePlayer supports real stereo. 6199 Utility::MixWithSat(_audioFrame.data_, 6200 _audioFrame.num_channels_, 6201 fileBuffer.get(), 6202 1, 6203 fileSamples); 6204 } 6205 else 6206 { 6207 // Replace ACM audio with file. 6208 // Currently file stream is always mono. 6209 // TODO(xians): Change the code when FilePlayer supports real stereo. 6210 _audioFrame.UpdateFrame(_channelId, 6211 -1, 6212 fileBuffer.get(), 6213 fileSamples, 6214 mixingFrequency, 6215 AudioFrame::kNormalSpeech, 6216 AudioFrame::kVadUnknown, 6217 1); 6218 6219 } 6220 return 0; 6221} 6222 6223WebRtc_Word32 6224Channel::MixAudioWithFile(AudioFrame& audioFrame, 6225 const int mixingFrequency) 6226{ 6227 assert(mixingFrequency <= 32000); 6228 6229 scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]); 6230 int fileSamples(0); 6231 6232 { 6233 CriticalSectionScoped cs(&_fileCritSect); 6234 6235 if (_outputFilePlayerPtr == NULL) 6236 { 6237 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6238 VoEId(_instanceId, _channelId), 6239 "Channel::MixAudioWithFile() file mixing failed"); 6240 return -1; 6241 } 6242 6243 // We should get the frequency we ask for. 6244 if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 6245 fileSamples, 6246 mixingFrequency) == -1) 6247 { 6248 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6249 VoEId(_instanceId, _channelId), 6250 "Channel::MixAudioWithFile() file mixing failed"); 6251 return -1; 6252 } 6253 } 6254 6255 if (audioFrame.samples_per_channel_ == fileSamples) 6256 { 6257 // Currently file stream is always mono. 6258 // TODO(xians): Change the code when FilePlayer supports real stereo. 6259 Utility::MixWithSat(audioFrame.data_, 6260 audioFrame.num_channels_, 6261 fileBuffer.get(), 6262 1, 6263 fileSamples); 6264 } 6265 else 6266 { 6267 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6268 "Channel::MixAudioWithFile() samples_per_channel_(%d) != " 6269 "fileSamples(%d)", 6270 audioFrame.samples_per_channel_, fileSamples); 6271 return -1; 6272 } 6273 6274 return 0; 6275} 6276 6277int 6278Channel::InsertInbandDtmfTone() 6279{ 6280 // Check if we should start a new tone. 6281 if (_inbandDtmfQueue.PendingDtmf() && 6282 !_inbandDtmfGenerator.IsAddingTone() && 6283 _inbandDtmfGenerator.DelaySinceLastTone() > 6284 kMinTelephoneEventSeparationMs) 6285 { 6286 WebRtc_Word8 eventCode(0); 6287 WebRtc_UWord16 lengthMs(0); 6288 WebRtc_UWord8 attenuationDb(0); 6289 6290 eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); 6291 _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); 6292 if (_playInbandDtmfEvent) 6293 { 6294 // Add tone to output mixer using a reduced length to minimize 6295 // risk of echo. 6296 _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, 6297 attenuationDb); 6298 } 6299 } 6300 6301 if (_inbandDtmfGenerator.IsAddingTone()) 6302 { 6303 WebRtc_UWord16 frequency(0); 6304 _inbandDtmfGenerator.GetSampleRate(frequency); 6305 6306 if (frequency != _audioFrame.sample_rate_hz_) 6307 { 6308 // Update sample rate of Dtmf tone since the mixing frequency 6309 // has changed. 6310 _inbandDtmfGenerator.SetSampleRate( 6311 (WebRtc_UWord16) (_audioFrame.sample_rate_hz_)); 6312 // Reset the tone to be added taking the new sample rate into 6313 // account. 6314 _inbandDtmfGenerator.ResetTone(); 6315 } 6316 6317 WebRtc_Word16 toneBuffer[320]; 6318 WebRtc_UWord16 toneSamples(0); 6319 // Get 10ms tone segment and set time since last tone to zero 6320 if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) 6321 { 6322 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6323 VoEId(_instanceId, _channelId), 6324 "Channel::EncodeAndSend() inserting Dtmf failed"); 6325 return -1; 6326 } 6327 6328 // Replace mixed audio with DTMF tone. 6329 for (int sample = 0; 6330 sample < _audioFrame.samples_per_channel_; 6331 sample++) 6332 { 6333 for (int channel = 0; 6334 channel < _audioFrame.num_channels_; 6335 channel++) 6336 { 6337 _audioFrame.data_[sample * _audioFrame.num_channels_ + channel] = 6338 toneBuffer[sample]; 6339 } 6340 } 6341 6342 assert(_audioFrame.samples_per_channel_ == toneSamples); 6343 } else 6344 { 6345 // Add 10ms to "delay-since-last-tone" counter 6346 _inbandDtmfGenerator.UpdateDelaySinceLastTone(); 6347 } 6348 return 0; 6349} 6350 6351WebRtc_Word32 6352Channel::GetPlayoutTimeStamp(WebRtc_UWord32& playoutTimestamp) 6353{ 6354 WebRtc_UWord32 timestamp(0); 6355 CodecInst currRecCodec; 6356 6357 if (_audioCodingModule.PlayoutTimestamp(timestamp) == -1) 6358 { 6359 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6360 "Channel::GetPlayoutTimeStamp() failed to read playout" 6361 " timestamp from the ACM"); 6362 return -1; 6363 } 6364 6365 WebRtc_UWord16 delayMS(0); 6366 if (_audioDeviceModulePtr->PlayoutDelay(&delayMS) == -1) 6367 { 6368 WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6369 "Channel::GetPlayoutTimeStamp() failed to read playout" 6370 " delay from the ADM"); 6371 return -1; 6372 } 6373 6374 WebRtc_Word32 playoutFrequency = _audioCodingModule.PlayoutFrequency(); 6375 if (_audioCodingModule.ReceiveCodec(currRecCodec) == 0) { 6376 if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) { 6377 playoutFrequency = 8000; 6378 } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) { 6379 playoutFrequency = 48000; 6380 } 6381 } 6382 timestamp -= (delayMS * (playoutFrequency/1000)); 6383 6384 playoutTimestamp = timestamp; 6385 6386 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 6387 "Channel::GetPlayoutTimeStamp() => playoutTimestamp = %lu", 6388 playoutTimestamp); 6389 return 0; 6390} 6391 6392void 6393Channel::ResetDeadOrAliveCounters() 6394{ 6395 _countDeadDetections = 0; 6396 _countAliveDetections = 0; 6397} 6398 6399void 6400Channel::UpdateDeadOrAliveCounters(bool alive) 6401{ 6402 if (alive) 6403 _countAliveDetections++; 6404 else 6405 _countDeadDetections++; 6406} 6407 6408int 6409Channel::GetDeadOrAliveCounters(int& countDead, int& countAlive) const 6410{ 6411 bool enabled; 6412 WebRtc_UWord8 timeSec; 6413 6414 _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, timeSec); 6415 if (!enabled) 6416 return (-1); 6417 6418 countDead = static_cast<int> (_countDeadDetections); 6419 countAlive = static_cast<int> (_countAliveDetections); 6420 return 0; 6421} 6422 6423WebRtc_Word32 6424Channel::SendPacketRaw(const void *data, int len, bool RTCP) 6425{ 6426 if (_transportPtr == NULL) 6427 { 6428 return -1; 6429 } 6430 if (!RTCP) 6431 { 6432 return _transportPtr->SendPacket(_channelId, data, len); 6433 } 6434 else 6435 { 6436 return _transportPtr->SendRTCPPacket(_channelId, data, len); 6437 } 6438} 6439 6440WebRtc_Word32 6441Channel::UpdatePacketDelay(const WebRtc_UWord32 timestamp, 6442 const WebRtc_UWord16 sequenceNumber) 6443{ 6444 WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 6445 "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 6446 timestamp, sequenceNumber); 6447 6448 WebRtc_Word32 rtpReceiveFrequency(0); 6449 6450 // Get frequency of last received payload 6451 rtpReceiveFrequency = _audioCodingModule.ReceiveFrequency(); 6452 6453 CodecInst currRecCodec; 6454 if (_audioCodingModule.ReceiveCodec(currRecCodec) == 0) { 6455 if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) { 6456 // Even though the actual sampling rate for G.722 audio is 6457 // 16,000 Hz, the RTP clock rate for the G722 payload format is 6458 // 8,000 Hz because that value was erroneously assigned in 6459 // RFC 1890 and must remain unchanged for backward compatibility. 6460 rtpReceiveFrequency = 8000; 6461 } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) { 6462 // We are resampling Opus internally to 32,000 Hz until all our 6463 // DSP routines can operate at 48,000 Hz, but the RTP clock 6464 // rate for the Opus payload format is standardized to 48,000 Hz, 6465 // because that is the maximum supported decoding sampling rate. 6466 rtpReceiveFrequency = 48000; 6467 } 6468 } 6469 6470 const WebRtc_UWord32 timeStampDiff = timestamp - _playoutTimeStampRTP; 6471 WebRtc_UWord32 timeStampDiffMs(0); 6472 6473 if (timeStampDiff > 0) 6474 { 6475 switch (rtpReceiveFrequency) { 6476 case 8000: 6477 timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 3); 6478 break; 6479 case 16000: 6480 timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 4); 6481 break; 6482 case 32000: 6483 timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 5); 6484 break; 6485 case 48000: 6486 timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff / 48); 6487 break; 6488 default: 6489 WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6490 VoEId(_instanceId, _channelId), 6491 "Channel::UpdatePacketDelay() invalid sample rate"); 6492 timeStampDiffMs = 0; 6493 return -1; 6494 } 6495 if (timeStampDiffMs > 5000) 6496 { 6497 timeStampDiffMs = 0; 6498 } 6499 6500 if (_averageDelayMs == 0) 6501 { 6502 _averageDelayMs = timeStampDiffMs; 6503 } 6504 else 6505 { 6506 // Filter average delay value using exponential filter (alpha is 6507 // 7/8). We derive 10*_averageDelayMs here (reduces risk of 6508 // rounding error) and compensate for it in GetDelayEstimate() 6509 // later. Adding 4/8 results in correct rounding. 6510 _averageDelayMs = ((_averageDelayMs*7 + 10*timeStampDiffMs + 4)>>3); 6511 } 6512 6513 if (sequenceNumber - _previousSequenceNumber == 1) 6514 { 6515 WebRtc_UWord16 packetDelayMs = 0; 6516 switch (rtpReceiveFrequency) { 6517 case 8000: 6518 packetDelayMs = static_cast<WebRtc_UWord16>( 6519 (timestamp - _previousTimestamp) >> 3); 6520 break; 6521 case 16000: 6522 packetDelayMs = static_cast<WebRtc_UWord16>( 6523 (timestamp - _previousTimestamp) >> 4); 6524 break; 6525 case 32000: 6526 packetDelayMs = static_cast<WebRtc_UWord16>( 6527 (timestamp - _previousTimestamp) >> 5); 6528 break; 6529 case 48000: 6530 packetDelayMs = static_cast<WebRtc_UWord16>( 6531 (timestamp - _previousTimestamp) / 48); 6532 break; 6533 } 6534 6535 if (packetDelayMs >= 10 && packetDelayMs <= 60) 6536 _recPacketDelayMs = packetDelayMs; 6537 } 6538 } 6539 6540 _previousSequenceNumber = sequenceNumber; 6541 _previousTimestamp = timestamp; 6542 6543 return 0; 6544} 6545 6546void 6547Channel::RegisterReceiveCodecsToRTPModule() 6548{ 6549 WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6550 "Channel::RegisterReceiveCodecsToRTPModule()"); 6551 6552 6553 CodecInst codec; 6554 const WebRtc_UWord8 nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 6555 6556 for (int idx = 0; idx < nSupportedCodecs; idx++) 6557 { 6558 // Open up the RTP/RTCP receiver for all supported codecs 6559 if ((_audioCodingModule.Codec(idx, codec) == -1) || 6560 (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 6561 { 6562 WEBRTC_TRACE( 6563 kTraceWarning, 6564 kTraceVoice, 6565 VoEId(_instanceId, _channelId), 6566 "Channel::RegisterReceiveCodecsToRTPModule() unable" 6567 " to register %s (%d/%d/%d/%d) to RTP/RTCP receiver", 6568 codec.plname, codec.pltype, codec.plfreq, 6569 codec.channels, codec.rate); 6570 } 6571 else 6572 { 6573 WEBRTC_TRACE( 6574 kTraceInfo, 6575 kTraceVoice, 6576 VoEId(_instanceId, _channelId), 6577 "Channel::RegisterReceiveCodecsToRTPModule() %s " 6578 "(%d/%d/%d/%d) has been added to the RTP/RTCP " 6579 "receiver", 6580 codec.plname, codec.pltype, codec.plfreq, 6581 codec.channels, codec.rate); 6582 } 6583 } 6584} 6585 6586int Channel::ApmProcessRx(AudioFrame& frame) { 6587 AudioProcessing* audioproc = _rxAudioProcessingModulePtr; 6588 // Register the (possibly new) frame parameters. 6589 if (audioproc->set_sample_rate_hz(frame.sample_rate_hz_) != 0) { 6590 LOG_FERR1(LS_WARNING, set_sample_rate_hz, frame.sample_rate_hz_); 6591 } 6592 if (audioproc->set_num_channels(frame.num_channels_, 6593 frame.num_channels_) != 0) { 6594 LOG_FERR1(LS_WARNING, set_num_channels, frame.num_channels_); 6595 } 6596 if (audioproc->ProcessStream(&frame) != 0) { 6597 LOG_FERR0(LS_WARNING, ProcessStream); 6598 } 6599 return 0; 6600} 6601 6602int Channel::SetSecondarySendCodec(const CodecInst& codec, 6603 int red_payload_type) { 6604 if (SetRedPayloadType(red_payload_type) < 0) { 6605 _engineStatisticsPtr->SetLastError( 6606 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6607 "SetSecondarySendCodec() Failed to register RED ACM"); 6608 return -1; 6609 } 6610 if (_audioCodingModule.RegisterSecondarySendCodec(codec) < 0) { 6611 _engineStatisticsPtr->SetLastError( 6612 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6613 "SetSecondarySendCodec() Failed to register secondary send codec in " 6614 "ACM"); 6615 return -1; 6616 } 6617 6618 return 0; 6619} 6620 6621void Channel::RemoveSecondarySendCodec() { 6622 _audioCodingModule.UnregisterSecondarySendCodec(); 6623} 6624 6625int Channel::GetSecondarySendCodec(CodecInst* codec) { 6626 if (_audioCodingModule.SecondarySendCodec(codec) < 0) { 6627 _engineStatisticsPtr->SetLastError( 6628 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6629 "GetSecondarySendCodec() Failed to get secondary sent codec from ACM"); 6630 return -1; 6631 } 6632 return 0; 6633} 6634 6635int Channel::SetRedPayloadType(int red_payload_type) { 6636 if (red_payload_type < 0) { 6637 _engineStatisticsPtr->SetLastError( 6638 VE_PLTYPE_ERROR, kTraceError, 6639 "SetRedPayloadType() invalid RED paylaod type"); 6640 return -1; 6641 } 6642 6643 CodecInst codec; 6644 bool found_red = false; 6645 6646 // Get default RED settings from the ACM database 6647 const int num_codecs = AudioCodingModule::NumberOfCodecs(); 6648 for (int idx = 0; idx < num_codecs; idx++) { 6649 _audioCodingModule.Codec(idx, codec); 6650 if (!STR_CASE_CMP(codec.plname, "RED")) { 6651 found_red = true; 6652 break; 6653 } 6654 } 6655 6656 if (!found_red) { 6657 _engineStatisticsPtr->SetLastError( 6658 VE_CODEC_ERROR, kTraceError, 6659 "SetRedPayloadType() RED is not supported"); 6660 return -1; 6661 } 6662 6663 codec.pltype = red_payload_type; 6664 if (_audioCodingModule.RegisterSendCodec(codec) < 0) { 6665 _engineStatisticsPtr->SetLastError( 6666 VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6667 "SetRedPayloadType() RED registration in ACM module failed"); 6668 return -1; 6669 } 6670 6671 if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) { 6672 _engineStatisticsPtr->SetLastError( 6673 VE_RTP_RTCP_MODULE_ERROR, kTraceError, 6674 "SetRedPayloadType() RED registration in RTP/RTCP module failed"); 6675 return -1; 6676 } 6677 return 0; 6678} 6679 6680} // namespace voe 6681} // namespace webrtc 6682