channel.cc revision e46c8d387587ba148e229a7bb18f1cc0708a2a87
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 22919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 116388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/channel.h" 126388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 136388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_device/include/audio_device.h" 146388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_processing/include/audio_processing.h" 156388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/audio_frame_operations.h" 166388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/process_thread.h" 176388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/rtp_dump.h" 186388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 196388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 216388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_base.h" 226388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_external_media.h" 236388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_rtp_rtcp.h" 246388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/output_mixer.h" 256388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/statistics.h" 266388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 276388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/utility.h" 28470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 29470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#if defined(_WIN32) 30470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <Qos.h> 31470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3350419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace webrtc { 3450419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace voe { 35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 366141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendData(FrameType frameType, 386141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t payloadType, 396141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t timeStamp, 406141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t* payloadData, 416141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t payloadSize, 42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const RTPFragmentationHeader* fragmentation) 43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," 46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " payloadSize=%u, fragmentation=0x%x)", 47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com frameType, payloadType, timeStamp, payloadSize, fragmentation); 48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_includeAudioLevelIndication) 50470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 51755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org assert(_rtpAudioProc.get() != NULL); 52470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store current audio level in the RTP/RTCP module. 53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The level will be used in combination with voice-activity state 54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (frameType) to add an RTP header extension 552853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetAudioLevel(_rtpAudioProc->level_estimator()->RMS()); 56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push data from ACM to RTP/RTCP-module to deliver audio frame for 59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packetization. 60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call will trigger Transport::SendPacket() from the RTP/RTCP module. 612853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadType, 63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeStamp, 64ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // Leaving the time when this frame was 65ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // received from the capture device as 66ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // undefined for voice for now. 67ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org -1, 68470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadData, 69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fragmentation) == -1) 71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData() failed to send data to RTP/RTCP module"); 75470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 78470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp = timeStamp; 79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType = payloadType; 80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 846141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 856141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::InFrameType(int16_t frameType) 86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::InFrameType(frameType=%d)", frameType); 89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 909a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1 indicates speech 92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendFrameType = (frameType == 1) ? 1 : 0; 93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 966141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 979213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnRxVadDetected(int vadDecision) 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnRxVadDetected(vadDecision=%d)", vadDecision); 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1029a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); 106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendPacket(int channel, const void *data, int len) 113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket(channel=%d, len=%d)", channel, len); 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() failed to send RTP packet due to" 124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " invalid transport object"); 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Insert extra RTP packet using if user has called the InsertExtraRTPPacket 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // API 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_insertExtraRTPPacket) 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1326141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* rtpHdr = (uint8_t*)data; 1336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t M_PT(0); 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_extraMarkerBit) 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com M_PT = 0x80; // set the M-bit 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com M_PT += _extraPayloadType; // set the payload type 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *(++rtpHdr) = M_PT; // modify the M|PT-byte within the RTP header 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket = false; // insert one packet only 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1436141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 1446141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t bufferLength = len; 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTP packet to a file (if RTP dump is enabled). 1476141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpOut.DumpPacket((const uint8_t*)data, len) == -1) 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP dump to output file failed"); 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External encryption 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encrypting) 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1579a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionRTPBufferPtr) 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for encryption buffer one time only 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTPBufferPtr = 1656141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org new uint8_t[kVoiceEngineMaxIpPacketSizeBytes]; 166512535097e543333584f268eb62fe81c9ac76cc6xians@webrtc.org memset(_encryptionRTPBufferPtr, 0, 167512535097e543333584f268eb62fe81c9ac76cc6xians@webrtc.org kVoiceEngineMaxIpPacketSizeBytes); 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform encryption (SRTP or external) 1716141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t encryptedBufferLength = 0; 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->encrypt(_channelId, 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTPBufferPtr, 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength, 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&encryptedBufferLength); 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encryptedBufferLength <= 0) 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ENCRYPTION_FAILED, 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, "Channel::SendPacket() encryption failed"); 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with encrypted buffer 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr = _encryptionRTPBufferPtr; 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength = encryptedBufferLength; 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using WebRtc socket transport 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport) 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendPacket(channel, bufferToSendPtr, 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP transmission using WebRtc" 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sockets failed"); 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using external transport transport 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2099a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendPacket(channel, 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP transmission using external" 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " transport failed"); 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendRTCPPacket(int channel, const void *data, int len) 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket(channel=%d, len=%d)", channel, len); 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2369a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 23783661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org if (_transportPtr == NULL) 23883661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org { 23983661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 24083661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org VoEId(_instanceId,_channelId), 24183661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org "Channel::SendRTCPPacket() failed to send RTCP packet" 24283661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org " due to invalid transport object"); 24383661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org return -1; 24483661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org } 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2476141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 2486141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t bufferLength = len; 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTCP packet to a file (if RTP dump is enabled). 2516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpOut.DumpPacket((const uint8_t*)data, len) == -1) 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTCP dump to output file failed"); 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External encryption 259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encrypting) 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2619a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionRTCPBufferPtr) 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for encryption buffer one time only 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTCPBufferPtr = 2696141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org new uint8_t[kVoiceEngineMaxIpPacketSizeBytes]; 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform encryption (SRTP or external). 2736141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t encryptedBufferLength = 0; 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->encrypt_rtcp(_channelId, 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTCPBufferPtr, 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength, 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&encryptedBufferLength); 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encryptedBufferLength <= 0) 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ENCRYPTION_FAILED, kTraceError, 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() encryption failed"); 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with encrypted buffer 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr = _encryptionRTCPBufferPtr; 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength = encryptedBufferLength; 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using WebRtc socket transport 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport) 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendRTCPPacket(channel, 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() transmission using WebRtc" 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sockets failed"); 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using external transport transport 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3129a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 313de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org if (_transportPtr == NULL) 314de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org { 315de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org return -1; 316de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org } 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendRTCPPacket(channel, 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() transmission using external" 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " transport failed"); 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return len; 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 3359213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnPlayTelephoneEvent(int32_t id, 3369213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t event, 3379213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint16_t lengthMs, 3389213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t volume) 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPlayTelephoneEvent(id=%d, event=%u, lengthMs=%u," 342fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " volume=%u)", id, event, lengthMs, volume); 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playOutbandDtmfEvent || (event > 15)) 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ignore callback since feedback is disabled or event is not a 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dtmf tone event. 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(_outputMixerPtr != NULL); 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playing out the Dtmf tone (if playout is enabled). 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reduce length of tone with 80ms to the reduce risk of echo. 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 3599213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnIncomingSSRCChanged(int32_t id, 3609213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t SSRC) 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingSSRCChanged(id=%d, SSRC=%d)", 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, SSRC); 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3666141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset RTP-module counters since a new incoming RTP stream is detected 3702853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetReceiveDataCountersRTP(); 3712853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetStatisticsRTP(); 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserver) 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3759a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Send new SSRC to registered observer using callback 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr->OnIncomingSSRCChanged(channel, SSRC); 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3859213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgvoid Channel::OnIncomingCSRCChanged(int32_t id, 3869213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t CSRC, 3879213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool added) 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingCSRCChanged(id=%d, CSRC=%d, added=%d)", 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, CSRC, added); 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3936141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserver) 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3989a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr->OnIncomingCSRCChanged(channel, CSRC, added); 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 4089213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnApplicationDataReceived(int32_t id, 4099213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t subType, 4109213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t name, 4119213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint16_t length, 4126141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t* data) 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnApplicationDataReceived(id=%d, subType=%u," 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " name=%u, length=%u)", 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, subType, name, length); 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4196141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserver) 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4249a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserverPtr) 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr->OnApplicationDataReceived(channel, 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com data, 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com length); 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4376141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnInitializeDecoder( 4399213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int32_t id, 4409213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int8_t payloadType, 441813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char payloadName[RTP_PAYLOAD_NAME_SIZE], 4429213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int frequency, 4439213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t channels, 4449213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t rate) 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder(id=%d, payloadType=%d, " 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "payloadName=%s, frequency=%u, channels=%u, rate=%u)", 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, payloadType, payloadName, frequency, channels, rate); 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 451ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org assert(VoEChannelId(id) == _channelId); 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 453f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst receiveCodec = {0}; 454f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst dummyCodec = {0}; 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pltype = payloadType; 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.plfreq = frequency; 458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.channels = channels; 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.rate = rate; 460f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 461ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 4627a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org _audioCodingModule.Codec(payloadName, &dummyCodec, frequency, channels); 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pacsize = dummyCodec.pacsize; 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register the new codec to the ACM 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(receiveCodec) == -1) 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 469ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org VoEId(_instanceId, _channelId), 470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder() invalid codec (" 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "pt=%d, name=%s) received - 1", payloadType, payloadName); 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 4809213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnPacketTimeout(int32_t id) 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout(id=%d)", id); 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4859a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(_callbackCritSectPtr); 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving || _externalTransport) 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4906141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that next OnReceivedPacket() callback will trigger 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // a VE_PACKET_RECEIPT_RESTARTED callback. 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut = true; 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver callback to the observer 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout() => " 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "CallbackOnError(VE_RECEIVE_PACKET_TIMEOUT)"); 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr->CallbackOnError(channel, 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RECEIVE_PACKET_TIMEOUT); 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 5079213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnReceivedPacket(int32_t id, 5089213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org RtpRtcpPacketType packetType) 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPacket(id=%d, packetType=%d)", 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, packetType); 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 514ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org assert(VoEChannelId(id) == _channelId); 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Notify only for the case when we have restarted an RTP session. 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpPacketTimedOut && (kPacketRtp == packetType)) 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5199a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(_callbackCritSectPtr); 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5226141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset timeout mechanism 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut = false; 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver callback to the observer 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout() =>" 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " CallbackOnError(VE_PACKET_RECEIPT_RESTARTED)"); 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr->CallbackOnError( 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel, 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_PACKET_RECEIPT_RESTARTED); 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 5399213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnPeriodicDeadOrAlive(int32_t id, 5409213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org RTPAliveType alive) 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPeriodicDeadOrAlive(id=%d, alive=%d)", id, alive); 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 54519da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org { 54619da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 54719da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org if (!_connectionObserver) 54819da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org return; 54919da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org } 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t channel = VoEChannelId(id); 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Use Alive as default to limit risk of false Dead detections 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool isAlive(true); 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Always mark the connection as Dead when the module reports kRtpDead 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kRtpDead == alive) 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isAlive = false; 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // It is possible that the connection is alive even if no RTP packet has 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // been received for a long time since the other side might use VAD/DTX 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and a low SID-packet update rate. 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((kRtpNoRtp == alive) && _playing) 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Detect Alive for all NetEQ states except for the case when we are 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in PLC_CNG state. 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // PLC_CNG <=> background noise only due to long expand or error. 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the case where the other side stops sending during CNG 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // state will be detected as Alive. Dead is is not set until after 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // missing RTCP packets for at least twelve seconds (handled 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // internally by the RTP/RTCP module). 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isAlive = (_outputSpeechType != AudioFrame::kPLCCNG); 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdateDeadOrAliveCounters(isAlive); 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Send callback to the registered observer 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserver) 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5839a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserverPtr) 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr->OnPeriodicDeadOrAlive(channel, isAlive); 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5916141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 5926141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::OnReceivedPayloadData(const uint8_t* payloadData, 5939213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint16_t payloadSize, 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtcRTPHeader* rtpHeader) 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData(payloadSize=%d," 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " payloadType=%u, audioChannel=%u)", 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.payloadType, 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->type.Audio.channel); 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6030870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com _lastRemoteTimeStamp = rtpHeader->header.timestamp; 6040870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playing) 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid inserting into NetEQ when we are not playing. Count the 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packet as discarded. 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "received packet is discarded since playing is not" 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " activated"); 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets++; 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push the incoming payload (parsed and ready for decoding) into the ACM 61816b6b90a82b796460bb20762761182c7d104cd2dtina.legrand@webrtc.org if (_audioCodingModule.IncomingPacket(payloadData, 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *rtpHeader) != 0) 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData() unable to push data to the ACM"); 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update the packet delay 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdatePacketDelay(rtpHeader->header.timestamp, 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.sequenceNumber); 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6349213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgint32_t Channel::GetAudioFrame(int32_t id, AudioFrame& audioFrame) 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame(id=%d)", id); 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms raw PCM data from the ACM (mixer limits output frequency) 64063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioCodingModule.PlayoutData10Ms(audioFrame.sample_rate_hz_, 6417a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org &audioFrame) == -1) 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); 6467859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // In all likelihood, the audio in this frame is garbage. We return an 6477859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // error so that the audio mixer module doesn't add it to the mix. As 6487859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // a result, it won't be played out and the actions skipped here are 6497859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // irrelevant. 6507859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org return -1; 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_RxVadDetection) 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdateRxVadDetection(audioFrame); 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Convert module ID to internal VoE channel ID 65963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.id_ = VoEChannelId(audioFrame.id_); 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store speech type for dead-or-alive detection 66163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _outputSpeechType = audioFrame.speech_type_; 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform far-end AudioProcessing module processing on the received signal 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxApmIsEnabled) 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ApmProcessRx(audioFrame); 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Output volume scaling 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputGain < 0.99f || _outputGain > 1.01f) 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::ScaleWithSat(_outputGain, audioFrame); 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale left and/or right channel(s) if stereo and master balance is 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // active 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_panLeft != 1.0f || _panRight != 1.0f) 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 68063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.num_channels_ == 1) 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Emulate stereo mode since panning is active. 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The mono signal is copied to both left and right channels here. 6844ecea3e1057eebf846af9b93abf8faf8571bc576andrew@webrtc.org AudioFrameOperations::MonoToStereo(&audioFrame); 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // For true stereo mode (when we are receiving a stereo signal), no 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // action is needed. 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Do the panning operation (the audio frame contains stereo at this 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stage) 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Scale(_panLeft, _panRight, audioFrame); 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Mix decoded PCM output with file if file mixing is enabled 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 69763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org MixAudioWithFile(audioFrame, audioFrame.sample_rate_hz_); 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Place channel in on-hold state (~muted) if on-hold is activated 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputIsOnHold) 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Mute(audioFrame); 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // External media 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7099a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 71063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (audioFrame.num_channels_ == 2); 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr->Process( 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kPlaybackPerChannel, 7166141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (int16_t*)audioFrame.data_, 71763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, 71863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.sample_rate_hz_, 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Record playout if enabled 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7259a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording && _outputFileRecorderPtr) 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7295398d9583b713f83db843a15f8bcc2ef8df23bccniklas.enbom@webrtc.org _outputFileRecorderPtr->RecordAudioToFile(audioFrame); 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Measure audio level (0-9) 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.ComputeLevel(audioFrame); 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7396141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 7409213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::NeededFrequency(int32_t id) 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::NeededFrequency(id=%d)", id); 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int highestNeeded = 0; 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Determine highest needed receive frequency 7486141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t receiveFrequency = _audioCodingModule.ReceiveFrequency(); 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Return the bigger of playout and receive frequency in the ACM. 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.PlayoutFrequency() > receiveFrequency) 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = _audioCodingModule.PlayoutFrequency(); 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = receiveFrequency; 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Special case, if we're playing a file on the playout side 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // we take that frequency into consideration as well 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is not needed on sending side, since the codec will 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // limit the spectrum anyway. 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7669a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr && _outputFilePlaying) 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_outputFilePlayerPtr->Frequency()>highestNeeded) 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded=_outputFilePlayerPtr->Frequency(); 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(highestNeeded); 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7796141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::CreateChannel(Channel*& channel, 7819213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int32_t channelId, 7829213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t instanceId) 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel(channelId=%d, instanceId=%d)", 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channelId, instanceId); 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = new Channel(channelId, instanceId); 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (channel == NULL) 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(instanceId,channelId), 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel() unable to allocate memory for" 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " channel"); 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 8019213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayNotification(int32_t id, uint32_t durationMs) 802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayNotification(id=%d, durationMs=%d)", 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 8119213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordNotification(int32_t id, uint32_t durationMs) 812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordNotification(id=%d, durationMs=%d)", 815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 8219213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayFileEnded(int32_t id) 822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded(id=%d)", id); 825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (id == _inputFilePlayerId) 827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 8289a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = false; 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => input file player module is" 834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (id == _outputFilePlayerId) 837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 8389a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlaying = false; 841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => output file player module is" 844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 8499213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordFileEnded(int32_t id) 850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded(id=%d)", id); 853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(id == _outputFileRecorderId); 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8569a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded() => output file recorder module is" 862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8659213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::Channel(int32_t channelId, 8669213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t instanceId) : 867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _instanceId(instanceId), 87022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _channelId(channelId), 871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule(*AudioCodingModule::Create( 87222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com VoEModuleId(instanceId, channelId))), 873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpIn(*RtpDump::CreateRtpDump()), 874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpOut(*RtpDump::CreateRtpDump()), 875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel(), 876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport(false), 877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr(NULL), 878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr(NULL), 879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr(NULL), 880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid conflict with other channels by adding 1024 - 1026, 881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // won't use as much as 1024 channels. 882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), 883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), 885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying(false), 886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlaying(false), 887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording(false), 88822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), 88922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), 890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia(false), 89122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputExternalMedia(false), 892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr(NULL), 893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr(NULL), 89422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionRTPBufferPtr(NULL), 89522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decryptionRTPBufferPtr(NULL), 89622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionRTCPBufferPtr(NULL), 89722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decryptionRTCPBufferPtr(NULL), 89822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _timeStamp(0), // This is just an offset, RTP module will add it's own random offset 89922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendTelephoneEventPayloadType(106), 9001de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtp_(0), 9011de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_(0), 90222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _numberOfDiscardedPackets(0), 90322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _engineStatisticsPtr(NULL), 9042919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _outputMixerPtr(NULL), 9052919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _transmitMixerPtr(NULL), 90622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _moduleProcessThreadPtr(NULL), 90722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _audioDeviceModulePtr(NULL), 90822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _voiceEngineObserverPtr(NULL), 90922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _callbackCritSectPtr(NULL), 91022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _transportPtr(NULL), 91122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionPtr(NULL), 912755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc(NULL), 91322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxAudioProcessingModulePtr(NULL), 91422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxVadObserverPtr(NULL), 91522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _oldVadDecision(-1), 91622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendFrameType(0), 917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr(NULL), 918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr(NULL), 91922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputIsOnHold(false), 92022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _externalPlayout(false), 9211b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing(false), 92222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inputIsOnHold(false), 92322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _playing(false), 92422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sending(false), 92522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _receiving(false), 92622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _mixFileWithMicrophone(false), 92722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rtpObserver(false), 92822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rtcpObserver(false), 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute(false), 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft(1.0f), 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight(1.0f), 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain(1.0f), 93322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encrypting(false), 93422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decrypting(false), 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent(false), 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent(false), 937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraPayloadType(0), 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket(false), 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraMarkerBit(false), 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp(0), 9410870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com _lastRemoteTimeStamp(0), 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType(0), 94322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _includeAudioLevelIndication(false), 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut(false), 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled(false), 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds(0), 947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver(false), 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr(NULL), 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections(0), 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections(0), 951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputSpeechType(AudioFrame::kNormalSpeech), 9521de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us(0), 953e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org least_required_delay_ms_(0), 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousTimestamp(0), 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recPacketDelayMs(20), 956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection(false), 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled(false), 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled(false), 95922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxNsIsEnabled(false) 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Channel() - ctor"); 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.ResetDtmf(); 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.Init(); 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9672853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RtpRtcp::Configuration configuration; 9682853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.id = VoEModuleId(instanceId, channelId); 9692853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio = true; 9702853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.incoming_data = this; 9712853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.incoming_messages = this; 9722853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.outgoing_transport = this; 9732853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.rtcp_feedback = this; 9742853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio_messages = this; 9752853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 9762853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); 9772853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create far end AudioProcessing Module 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr = AudioProcessing::Create( 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEModuleId(instanceId, channelId)); 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::~Channel() 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::~Channel() - dtor"); 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kPlaybackPerChannel); 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMedia) 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kRecordingPerChannel); 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopSend(); 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopPlayout(); 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 10009a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr) 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->StopPlayingFile(); 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr = NULL; 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The order to safely shutdown modules in a channel is: 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1. De-register callbacks in modules 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 2. De-register modules in process thread 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 3. Destroy modules 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterTransportCallback(NULL) == -1) 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register transport callback" 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterVADCallback(NULL) == -1) 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register VAD callback" 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register modules in process thread 10432853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()) == -1) 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to deregister RTP/RTCP module"); 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy modules 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioCodingModule::Destroy(&_audioCodingModule); 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr != NULL) 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioProcessing::Destroy(_rxAudioProcessingModulePtr); // far end APM 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr = NULL; 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // End of modules shutdown 1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete other objects 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpIn); 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpOut); 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _encryptionRTPBufferPtr; 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _decryptionRTPBufferPtr; 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _encryptionRTCPBufferPtr; 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _decryptionRTCPBufferPtr; 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_callbackCritSect; 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_fileCritSect; 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10716141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Init() 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init()"); 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Initial sanity 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_engineStatisticsPtr == NULL) || 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_moduleProcessThreadPtr == NULL)) 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() must call SetEngineInformation() first"); 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add modules to process thread (for periodic schedulation) 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool processThreadFail = 10912853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ((_moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()) != 0) || 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com false); 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (processThreadFail) 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() modules not registered"); 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1100c450a1966965fbb3c16ec6d02c3d5cbec67df500pwestin@webrtc.org // --- ACM initialization 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.InitializeReceiver() == -1) || 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_AVT 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // out-of-band Dtmf tones are played out by default 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.SetDtmfPlayoutStatus(true) == -1) || 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.InitializeSender() == -1)) 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to initialize the ACM - 1"); 1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- RTP/RTCP module initialization 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that RTCP is enabled by default for the created channel. 1118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the module will keep generating RTCP until it is explicitly 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // disabled by the user. 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // After StopListen (when no sockets exists), RTCP packets will no longer 1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // be transmitted since the Transport object will then be invalid. 1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool rtpRtcpFail = 1124b7edd065306329309dac6767fe4914c185f941f8turaj@webrtc.org ((_rtpRtcpModule->SetTelephoneEventForwardToDecoder(true) == -1) || 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTCP is enabled by default 11262853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->SetRTCPStatus(kRtcpCompound) == -1)); 1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpRtcpFail) 1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() RTP/RTCP module not initialized"); 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all permanent callbacks 1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool fail = 1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterTransportCallback(this) == -1) || 1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterVADCallback(this) == -1); 1139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fail) 1141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() callbacks not registered"); 1145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all supported codecs to the receiving side of the 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTP/RTCP module 1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 11526141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 11577a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if ((_audioCodingModule.Codec(idx, &codec) == -1) || 11582853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to register %s (%d/%d/%d/%d) " 1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "to RTP/RTCP receiver", 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() %s (%d/%d/%d/%d) has been added to " 1172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP receiver", 1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that PCMU is used as default codec on the sending side 11784517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SetSendCodec(codec); 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register default PT for outband 'telephone-event' 1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "telephone-event")) 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 11862853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || 1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterReceiveCodec(codec) == -1)) 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register outband " 1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "'telephone-event' (%d/%d) correctly", 1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "CN")) 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.RegisterSendCodec(codec) == -1) || 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterReceiveCodec(codec) == -1) || 12012853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register CN (%d/%d) " 1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly - 1", 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_RED 1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register RED to the receiving side of the ACM. 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will not receive an OnInitializeDecoder() callback for RED. 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "RED")) 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) == -1) 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register RED (%d/%d) " 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly", 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1226684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize the far end AP module 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Using 8 kHz as initial Fs, the same as in transmission. Might be 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // changed at the first receiving audio. 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr == NULL) 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NO_MEMORY, kTraceCritical, 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to create the far-end AudioProcessing" 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " module"); 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->set_sample_rate_hz(8000)) 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to set the sample rate to 8K for" 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " far-end AP module"); 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->set_num_channels(1, 1) != 0) 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOUNDCARD_ERROR, kTraceWarning, 1251755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Init() failed to set channels for the primary audio stream"); 1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->high_pass_filter()->Enable( 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_HP_DEFAULT_STATE) != 0) 1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to set the high-pass filter for" 1260fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " far-end AP module"); 1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->set_level( 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE) != 0) 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set noise reduction level for far-end" 1269fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " AP module"); 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->Enable( 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_STATE) != 0) 1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set noise reduction state for far-end" 1277fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " AP module"); 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_mode( 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (GainControl::Mode)WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_MODE) != 0) 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set AGC mode for far-end AP module"); 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->Enable( 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_STATE) != 0) 1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set AGC state for far-end AP module"); 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12986141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetEngineInformation(Statistics& engineStatistics, 1300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OutputMixer& outputMixer, 1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com voe::TransmitMixer& transmitMixer, 1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessThread& moduleProcessThread, 1303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioDeviceModule& audioDeviceModule, 1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoiceEngineObserver* voiceEngineObserver, 1305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionWrapper* callbackCritSect) 1306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetEngineInformation()"); 1309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr = &engineStatistics; 1310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr = &outputMixer; 1311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transmitMixerPtr = &transmitMixer, 1312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _moduleProcessThreadPtr = &moduleProcessThread; 1313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioDeviceModulePtr = &audioDeviceModule; 1314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = voiceEngineObserver; 1315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSectPtr = callbackCritSect; 1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13196141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateLocalTimeStamp() 1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 132363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13276141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartPlayout() 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayout()"); 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playing) 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 13361b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 13371b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 13381b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Add participant as candidates for mixing. 13391b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) 13401b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 13411b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 13421b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 13431b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StartPlayout() failed to add participant to mixer"); 13441b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 13451b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playing = true; 1349ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1350ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1351ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 1352ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13566141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopPlayout() 1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayout()"); 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playing) 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 13651b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 13661b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 13671b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Remove participant as candidates for mixing 13681b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) 13691b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 13701b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 13711b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 13721b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StopPlayout() failed to remove participant from mixer"); 13731b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 13741b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playing = false; 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13836141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartSend() 1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartSend()"); 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1389e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // A lock is needed because |_sending| can be accessed or modified by 1390e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // another thread at the same time. 13919a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1392e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1393e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org if (_sending) 1394e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org { 1395e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org return 0; 1396e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org } 1397e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = true; 1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1399e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 14002853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(true) != 0) 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to start sending"); 14059a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1406e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = false; 1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1409e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14136141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopSend() 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopSend()"); 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1419e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // A lock is needed because |_sending| can be accessed or modified by 1420e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // another thread at the same time. 14219a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1422e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1423e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org if (!_sending) 1424e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org { 1425e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org return 0; 1426e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org } 1427e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = false; 1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1429e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset sending SSRC and sequence number and triggers direct transmission 1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // of RTCP BYE 14322853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(false) == -1 || 14332853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetSendDataCountersRTP() == -1) 1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to stop sending"); 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14436141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartReceiving() 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartReceiving()"); 1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving) 1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _receiving = true; 1453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets = 0; 1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14576141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopReceiving() 1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopReceiving()"); 1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_receiving) 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1466684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1467af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org // Recover DTMF detection status. 14686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t ret = _rtpRtcpModule->SetTelephoneEventForwardToDecoder(true); 1469af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org if (ret != 0) { 1470af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org _engineStatisticsPtr->SetLastError( 1471af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org VE_INVALID_OPERATION, kTraceWarning, 1472af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org "StopReceiving() failed to restore telephone-event status."); 1473af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org } 1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RegisterReceiveCodecsToRTPModule(); 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _receiving = false; 1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14796141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetNetEQPlayoutMode(NetEqModes mode) 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetNetEQPlayoutMode()"); 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioPlayoutMode playoutMode(voice); 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqDefault: 1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = voice; 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqStreaming: 1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = streaming; 1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqFax: 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = fax; 1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1496b718619f0ab1ad984e334dd90f67e08bb6d80af3roosa@google.com case kNetEqOff: 1497b718619f0ab1ad984e334dd90f67e08bb6d80af3roosa@google.com playoutMode = off; 1498b718619f0ab1ad984e334dd90f67e08bb6d80af3roosa@google.com break; 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetPlayoutMode(playoutMode) != 0) 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetNetEQPlayoutMode() failed to set playout mode"); 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15106141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetEQPlayoutMode(NetEqModes& mode) 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const AudioPlayoutMode playoutMode = _audioCodingModule.PlayoutMode(); 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (playoutMode) 1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case voice: 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqDefault; 1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case streaming: 1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqStreaming; 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case fax: 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqFax; 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1525b718619f0ab1ad984e334dd90f67e08bb6d80af3roosa@google.com case off: 1526b718619f0ab1ad984e334dd90f67e08bb6d80af3roosa@google.com mode = kNetEqOff; 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetEQPlayoutMode() => mode=%u", mode); 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15346141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOnHoldStatus(bool enable, OnHoldModes mode) 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOnHoldStatus()"); 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (mode == kHoldSendAndPlay) 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputIsOnHold = enable; 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputIsOnHold = enable; 1543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (mode == kHoldPlayOnly) 1545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputIsOnHold = enable; 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (mode == kHoldSendOnly) 1549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputIsOnHold = enable; 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15556141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOnHoldStatus(bool& enabled, OnHoldModes& mode) 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetOnHoldStatus()"); 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (_outputIsOnHold || _inputIsOnHold); 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputIsOnHold && _inputIsOnHold) 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldSendAndPlay; 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (_outputIsOnHold && !_inputIsOnHold) 1566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldPlayOnly; 1568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (!_outputIsOnHold && _inputIsOnHold) 1570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldSendOnly; 1572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetOnHoldStatus() => enabled=%d, mode=%d", 1575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, mode); 1576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15796141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 1581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterVoiceEngineObserver()"); 15849a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 1587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 1590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterVoiceEngineObserver() observer already enabled"); 1591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = &observer; 1594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterVoiceEngineObserver() 1599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterVoiceEngineObserver()"); 16029a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_voiceEngineObserverPtr) 1605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterVoiceEngineObserver() observer already disabled"); 1609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = NULL; 1612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendCodec(CodecInst& codec) 1617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 16187a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org return (_audioCodingModule.SendCodec(&codec)); 1619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16216141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecCodec(CodecInst& codec) 1623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 16247a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org return (_audioCodingModule.ReceiveCodec(&codec)); 1625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16276141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCodec(const CodecInst& codec) 1629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCodec()"); 1632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterSendCodec(codec) != 0) 1634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to ACM"); 1637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16402853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 16422853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 16432853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 1646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to" 1648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " RTP/RTCP module"); 1649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16532853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) 1654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to set audio packet size"); 1657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16636141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) 1665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetVADStatus(mode=%d)", mode); 1668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // To disable VAD, DTX must be disabled too 1669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disableDTX = ((enableVAD == false) ? true : disableDTX); 1670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetVAD(!disableDTX, enableVAD, mode) != 0) 1671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetVADStatus() failed to set VAD"); 1675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16806141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) 1682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetVADStatus"); 16857a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (_audioCodingModule.VAD(&disabledDTX, &enabledVAD, &mode) != 0) 1686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetVADStatus() failed to get VAD status"); 1690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disabledDTX = !disabledDTX; 1693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16966141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRecPayloadType(const CodecInst& codec) 1698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRecPayloadType()"); 1701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playing) 1703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while playing"); 1707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving) 1710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_LISTENING, kTraceError, 1713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while listening"); 1714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codec.pltype == -1) 1718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register the selected codec (RTP/RTCP module and ACM) 1720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17216141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t pltype(-1); 1722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst rxCodec = codec; 1723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get payload type for the given codec 17252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ReceivePayloadType(rxCodec, &pltype); 1726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rxCodec.pltype = pltype; 1727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17282853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DeRegisterReceivePayload(pltype) != 0) 1729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 1732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 1733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module deregistration " 1734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 1735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.UnregisterReceiveCodec(rxCodec.pltype) != 0) 1738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM deregistration failed - 1"); 1742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17472853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 1748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // First attempt to register failed => de-register and try again 17502853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterReceivePayload(codec.pltype); 17512853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 1752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module registration failed"); 1756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 1760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.UnregisterReceiveCodec(codec.pltype); 1762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 1763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM registration failed - 1"); 1767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17736141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecPayloadType(CodecInst& codec) 1775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType()"); 17786141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(-1); 17792853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->ReceivePayloadType(codec, &payloadType) != 0) 1780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 178237198007eab6731fa0f77866155dd4f2b332a262henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRecPayloadType() failed to retrieve RX payload type"); 1784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = payloadType; 1787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType() => pltype=%u", codec.pltype); 1789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17926141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMREncFormat(AmrMode mode) 1794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMREncFormat()"); 1797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18026141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRDecFormat(AmrMode mode) 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRDecFormat()"); 1807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18126141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRWbEncFormat(AmrMode mode) 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRWbEncFormat()"); 1817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 1819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18236141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRWbDecFormat(AmrMode mode) 1825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRWbDecFormat()"); 1828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 1830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) 1835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCNPayloadType()"); 1838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 18406141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t samplingFreqHz(-1); 18414517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org const int kMono = 1; 1842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (frequency == kFreq32000Hz) 1843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 32000; 1844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (frequency == kFreq16000Hz) 1845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 16000; 1846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18477a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (_audioCodingModule.Codec("CN", &codec, samplingFreqHz, kMono) == -1) 1848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to retrieve default CN codec " 1852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "settings"); 1853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Modify the payload type (must be set to dynamic range) 1857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = type; 1858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterSendCodec(codec) != 0) 1860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to ACM"); 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18672853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 18692853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 18702853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to RTP/RTCP " 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18826141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACInitTargetRate(int rateBps, bool useFixedFrameSize) 1884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACInitTargetRate()"); 1887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 18897a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (_audioCodingModule.SendCodec(&sendCodec) == -1) 1890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 1893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() failed to retrieve send codec"); 1894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 1897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This API is only valid if iSAC is setup to run in channel-adaptive 1899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // mode. 1900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We do not validate the adaptive mode here. It is done later in the 1901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ConfigISACBandwidthEstimator() API. 1902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 1904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() send codec is not iSAC"); 1905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19086141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t initFrameSizeMsec(0); 1909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 1910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that 0 is a valid and corresponds to "use default 1912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps != 0 && 1913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rateBps < kVoiceEngineMinIsacInitTargetRateBpsWb) || 1914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsWb)) 1915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 1918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() invalid target rate - 1"); 1919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 30 or 60ms 19226141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org initFrameSizeMsec = (uint8_t)(sendCodec.pacsize / 16); 1923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 1925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps != 0 && 1927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rateBps < kVoiceEngineMinIsacInitTargetRateBpsSwb) || 1928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsSwb)) 1929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 1932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() invalid target rate - 2"); 1933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 19356141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org initFrameSizeMsec = (uint8_t)(sendCodec.pacsize / 32); // 30ms 1936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.ConfigISACBandwidthEstimator( 1939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com initFrameSizeMsec, rateBps, useFixedFrameSize) == -1) 1940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() iSAC BWE config failed"); 1944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19506141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACMaxRate(int rateBps) 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACMaxRate()"); 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 19577a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (_audioCodingModule.SendCodec(&sendCodec) == -1) 1958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() failed to retrieve send codec"); 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 1965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This API is only valid if iSAC is selected as sending codec. 1967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() send codec is not iSAC"); 1970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 1973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps < kVoiceEngineMinIsacMaxRateBpsWb) || 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacMaxRateBpsWb)) 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() invalid max rate - 1"); 1980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps < kVoiceEngineMinIsacMaxRateBpsSwb) || 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacMaxRateBpsSwb)) 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 1990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() invalid max rate - 2"); 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() unable to set max rate while sending"); 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set the maximum instantaneous rate of iSAC (works for both adaptive 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and non-adaptive mode) 2004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetISACMaxRate(rateBps) == -1) 2005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() failed to set max rate"); 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACMaxPayloadSize(int sizeBytes) 2017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACMaxPayloadSize()"); 2020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 20217a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (_audioCodingModule.SendCodec(&sendCodec) == -1) 2022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() failed to retrieve send codec"); 2026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() send codec is not iSAC"); 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 2036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesWb) || 2038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesWb)) 2039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() invalid max payload - 1"); 2043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 2047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesSwb) || 2049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesSwb)) 2050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() invalid max payload - 2"); 2054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 2058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 2061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() unable to set max rate while sending"); 2062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetISACMaxPayloadSize(sizeBytes) == -1) 2066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() failed to set max payload size"); 2070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20756141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t Channel::RegisterExternalTransport(Transport& transport) 2076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalTransport()"); 2079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20809a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 2083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, 2085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() external transport already enabled"); 2087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = true; 2090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = &transport; 2091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20946141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalTransport() 2096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalTransport()"); 2099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21009a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 210183661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org 2102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_transportPtr) 2103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() external transport already " 2107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "disabled"); 2108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = false; 2111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = NULL; 2112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() all transport is disabled"); 2114684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org return 0; 2115684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 2116684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 21176141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t Channel::ReceivedRTPPacket(const int8_t* data, int32_t length) { 21180c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 21190c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTPPacket()"); 2120684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 21210c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTP packet 21221de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(false); 2123684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 21240c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Dump the RTP packet to a file (if RTP dump is enabled). 21256141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpIn.DumpPacket((const uint8_t*)data, 21266141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t)length) == -1) { 21270c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 21280c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VoEId(_instanceId,_channelId), 21290c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::SendPacket() RTP dump to input file failed"); 21300c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 21310c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 21320c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Deliver RTP packet to RTP/RTCP module for parsing 21330c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // The packet will be pushed back to the channel thru the 21340c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // OnReceivedPayloadData callback so we don't push it to the ACM here 21356141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, 21366141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t)length) == -1) { 21370c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 21380c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 21390c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::IncomingRTPPacket() RTP packet is invalid"); 21400c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 21410c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org return 0; 21420c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org} 21430c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 21446141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t Channel::ReceivedRTCPPacket(const int8_t* data, int32_t length) { 21450c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 21460c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTCPPacket()"); 21470c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTCP packet 21481de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(true); 21490c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 21500c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Dump the RTCP packet to a file (if RTP dump is enabled). 21516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpIn.DumpPacket((const uint8_t*)data, 21526141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t)length) == -1) { 21530c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 21540c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VoEId(_instanceId,_channelId), 21550c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::SendPacket() RTCP dump to input file failed"); 21560c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 2157684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 21580c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Deliver RTCP packet to RTP/RTCP module for parsing 21596141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, 21606141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t)length) == -1) { 21610c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 21620c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 21630c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::IncomingRTPPacket() RTCP packet is invalid"); 21640c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 21650c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org return 0; 2166684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 2167684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 21686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetPacketTimeoutNotification(bool enable, int timeoutSeconds) 2170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetPacketTimeoutNotification()"); 2173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable) 2174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 21756141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t RTPtimeoutMS = 1000*timeoutSeconds; 21766141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t RTCPtimeoutMS = 0; 21772853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPacketTimeout(RTPtimeoutMS, RTCPtimeoutMS); 2178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled = true; 2179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds = timeoutSeconds; 2180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 21832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPacketTimeout(0, 0); 2184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled = false; 2185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds = 0; 2186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21906141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPacketTimeoutNotification(bool& enabled, int& timeoutSeconds) 2192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPacketTimeoutNotification()"); 2195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = _rtpPacketTimeOutIsEnabled; 2196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 2197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeoutSeconds = _rtpTimeOutSeconds; 2199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 2201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPacketTimeoutNotification() => enabled=%d," 2202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " timeoutSeconds=%d", 2203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, timeoutSeconds); 2204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22076141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterDeadOrAliveObserver(VoEConnectionObserver& observer) 2209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterDeadOrAliveObserver()"); 22129a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserverPtr) 2215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, kTraceError, 2217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterDeadOrAliveObserver() observer already enabled"); 2218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr = &observer; 2222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver = true; 2223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22276141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterDeadOrAliveObserver() 2229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterDeadOrAliveObserver()"); 22329a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_connectionObserverPtr) 2235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterDeadOrAliveObserver() observer already disabled"); 2239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver = false; 2243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr = NULL; 2244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22486141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetPeriodicDeadOrAliveStatus(bool enable, int sampleTimeSeconds) 2250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetPeriodicDeadOrAliveStatus()"); 2253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_connectionObserverPtr) 2254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 2256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetPeriodicDeadOrAliveStatus() connection observer has" 2257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " not been registered"); 2258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable) 2260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ResetDeadOrAliveCounters(); 2262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enabled(false); 22646141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t currentSampleTimeSec(0); 2265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store last state (will be used later if dead-or-alive is disabled). 22662853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, currentSampleTimeSec); 2267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update the dead-or-alive state. 22682853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetPeriodicDeadOrAliveStatus( 22696141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org enable, (uint8_t)sampleTimeSeconds) != 0) 2270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 2273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetPeriodicDeadOrAliveStatus() failed to set dead-or-alive " 2275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "status"); 2276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!enable) 2279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Restore last utilized sample time. 2281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Without this, the sample time would always be reset to default 2282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (2 sec), each time dead-or-alived was disabled without sample-time 2283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // parameter. 22842853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPeriodicDeadOrAliveStatus(enable, 2285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com currentSampleTimeSec); 2286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22906141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds) 2292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 22932853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus( 2294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, 22956141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint8_t&)sampleTimeSeconds); 2296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 2297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPeriodicDeadOrAliveStatus() => enabled=%d," 2298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sampleTimeSeconds=%d", 2299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, sampleTimeSeconds); 2300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(const char* fileName, 23049213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 23059213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 23069213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 23079213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 23089213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," 2313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " format=%d, volumeScaling=%5.3f, startPosition=%d, " 2314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 2315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 2316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 2318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 2321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 2322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 23269a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2328b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 2329b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2330b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2331b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2332b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 2333b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2335b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2336b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, (const FileFormats)format); 2337b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2338b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 2339b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2340b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 2341b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 234231d30700d638c4cfa47c26cac7cb00c7232874c9henrike@webrtc.org "StartPlayingFileLocally() filePlayer format is not correct"); 2343b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 2344b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23466141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2348b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile( 2349b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org fileName, 2350b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org loop, 2351b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org startPosition, 2352b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 2353b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 2354b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, 2355b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const CodecInst*)codecInst) != 0) 2356b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2357b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 2358b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_BAD_FILE, kTraceError, 2359b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to start file playout"); 2360b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 2361b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2362b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 2363b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 2364b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2365b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 2366b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = true; 2367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2368ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2369ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 2370066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 2371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(InStream* stream, 23769213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 23779213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 23789213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 23799213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(format=%d," 2384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 2385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 2386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 2388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() NULL as input stream"); 2392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 2397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 2400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 2401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 24059a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2406b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2407b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Destroy the old instance 2408b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 2409b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2410b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2411b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2412b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 2413b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2414b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2415b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Create the instance 2416b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2417b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, 2418b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const FileFormats)format); 2419b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2420b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 2421b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2422b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 2423b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 2424b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFileLocally() filePlayer format isnot correct"); 2425b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 2426b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2427b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 24286141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2429b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2430b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 2431b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 2432b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 2433b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, codecInst) != 0) 2434b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2435b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2436b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to " 2437b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "start file playout"); 2438b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 2439b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2440b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 2441b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 2442b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2443b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 2444b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = true; 2445b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2446ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2447ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 2448066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 2449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileLocally() 2454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileLocally()"); 2457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFilePlaying) 2459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileLocally() isnot playing"); 2463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 24679a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2468b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 2469b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StopPlayingFile() != 0) 2470b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 2471b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 2472b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 2473b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() could not stop playing"); 2474b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 2475b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 2476b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2477b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2478b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 2479b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = false; 2480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2481b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // _fileCritSect cannot be taken while calling 2482b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // SetAnonymousMixibilityStatus. Refer to comments in 2483b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // StartPlayingFileLocally(const char* ...) for more details. 2484066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) 2485066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org { 2486066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org _engineStatisticsPtr->SetLastError( 2487066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 2488b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() failed to stop participant from playing as" 2489b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "file in the mixer"); 2490066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 2491066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org } 2492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileLocally() const 2497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileLocally()"); 2500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25016141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org return (int32_t)_outputFilePlaying; 2502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2504ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.orgint Channel::RegisterFilePlayingToMixer() 2505ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org{ 2506ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // Return success for not registering for file playing to mixer if: 2507ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 1. playing file before playout is started on that channel. 2508ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 2. starting playout without file playing on that channel. 2509ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (!_playing || !_outputFilePlaying) 2510ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 2511ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 2512ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 2513ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2514ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // |_fileCritSect| cannot be taken while calling 2515ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // SetAnonymousMixabilityStatus() since as soon as the participant is added 2516ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // frames can be pulled by the mixer. Since the frames are generated from 2517ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // the file, _fileCritSect will be taken. This would result in a deadlock. 2518ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) 2519ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 2520ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2521ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlaying = false; 2522ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _engineStatisticsPtr->SetLastError( 2523ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 2524ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org "StartPlayingFile() failed to add participant as file to mixer"); 2525ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 2526ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2527ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr = NULL; 2528ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 2529ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 2530ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2531ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 2532ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org} 2533ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 25349213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgint Channel::ScaleLocalFilePlayout(float scale) 2535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ScaleLocalFilePlayout(scale=%5.3f)", scale); 2538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25399a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFilePlaying) 2542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "ScaleLocalFilePlayout() isnot playing"); 2546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_outputFilePlayerPtr == NULL) || 2549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_outputFilePlayerPtr->SetAudioScaling(scale) != 0)) 2550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetAudioScaling() failed to scale the playout"); 2554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::GetLocalPlayoutPosition(int& positionMs) 2561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetLocalPlayoutPosition(position=?)"); 2564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25656141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t position; 2566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25679a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 2570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalPlayoutPosition() filePlayer instance doesnot exist"); 2574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr->GetPlayoutPosition(position) != 0) 2578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalPlayoutPosition() failed"); 2582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com positionMs = position; 2585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(const char* fileName, 25909213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 25919213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 25929213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 25939213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 25949213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " 2599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " 2600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 2601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 2602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 2604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 2607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer is playing"); 2608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 26119a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 2615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 2622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 2624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 2626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 2630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 26336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile( 2636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, 2637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com loop, 2638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, 2639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, 2640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime, 2641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, 2642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const CodecInst*)codecInst) != 0) 2643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start file playout"); 2647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = true; 2654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(InStream* stream, 26599213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 26609213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 26619213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 26629213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(format=%d, " 2667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 2668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 2669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 2671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone NULL as input stream"); 2675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 2679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 2682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() is playing"); 2683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 26869a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 2690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 2697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 2699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 2701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingInputFile() filePlayer format isnot correct"); 2705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27086141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 2711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, notificationTime, 2712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, codecInst) != 0) 2713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start " 2716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "file playout"); 2717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2722ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = true; 2725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileAsMicrophone() 2730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileAsMicrophone()"); 2733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputFilePlaying) 2735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileAsMicrophone() isnot playing"); 2739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27429a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StopPlayingFile() != 0) 2744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFile() could not stop playing"); 2748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = false; 2754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileAsMicrophone() const 2759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileAsMicrophone()"); 2762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _inputFilePlaying; 2764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27669213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgint Channel::ScaleFileAsMicrophonePlayout(float scale) 2767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ScaleFileAsMicrophonePlayout(scale=%5.3f)", scale); 2770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27719a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputFilePlaying) 2774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "ScaleFileAsMicrophonePlayout() isnot playing"); 2778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_inputFilePlayerPtr == NULL) || 2782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_inputFilePlayerPtr->SetAudioScaling(scale) != 0)) 2783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetAudioScaling() failed to scale playout"); 2787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2793813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.orgint Channel::StartRecordingPlayout(const char* fileName, 2794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout(fileName=%s)", fileName); 2798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 28076141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 281040197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org if ((codecInst != NULL) && 281140197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org ((codecInst->channels < 1) || (codecInst->channels > 2))) 2812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 28349a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile( 2855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, (const CodecInst&)*codecInst, notificationTime) != 0) 2856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingAudioFile() failed to start file recording"); 2860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartRecordingPlayout(OutStream* stream, 2872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout()"); 2876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 28856141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codecInst != NULL && codecInst->channels != 1) 2889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 29119a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, 2932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime) != 0) 2933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() failed to " 2936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "start file recording"); 2937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2942ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopRecordingPlayout() 2950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 2952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRecordingPlayout()"); 2953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFileRecording) 2955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), 2957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecordingPlayout() isnot recording"); 2958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 29629a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StopRecording() != 0) 2965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecording() could not stop recording"); 2969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 2975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 2980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMixWithMicStatus(bool mix) 2981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mixFileWithMicrophone=mix; 2983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 29866141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevel(uint32_t& level) const 2987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 29886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t currentLevel = _outputAudioLevel.Level(); 29896141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 2990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevel() => level=%u", level); 2993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 29976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevelFullRange(uint32_t& level) const 2998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 29996141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t currentLevel = _outputAudioLevel.LevelFullRange(); 30006141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 3001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevelFullRange() => level=%u", level); 3004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMute(bool enable) 3009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMute(enable=%d)", enable); 3012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute = enable; 3013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 3017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Mute() const 3018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _mute; 3020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOutputVolumePan(float left, float right) 3024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOutputVolumePan()"); 3027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft = left; 3028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight = right; 3029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOutputVolumePan(float& left, float& right) const 3034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com left = _panLeft; 3036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com right = _panRight; 3037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetOutputVolumePan() => left=%3.2f, right=%3.2f", left, right); 3040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetChannelOutputVolumeScaling(float scaling) 3045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetChannelOutputVolumeScaling()"); 3048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain = scaling; 3049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetChannelOutputVolumeScaling(float& scaling) const 3054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaling = _outputGain; 3056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetChannelOutputVolumeScaling() => scaling=%3.2f", scaling); 3059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterExternalEncryption(Encryption& encryption) 3064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalEncryption()"); 3067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 30689a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 3071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalEncryption() encryption already enabled"); 3075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = &encryption; 3079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = true; 3081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = true; 3082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalEncryption() 3088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalEncryption()"); 3091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 30929a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionPtr) 3095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalEncryption() encryption already disabled"); 3099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = false; 3103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = false; 3104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = NULL; 3106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventOutband(unsigned char eventCode, 3111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, int attenuationDb, 3112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 3113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", 3116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 3117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent = playDtmfEvent; 3119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 31202853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, 3121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb) != 0) 3122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_DTMF_FAILED, 3125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 3126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendTelephoneEventOutband() failed to send event"); 3127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventInband(unsigned char eventCode, 3133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, 3134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int attenuationDb, 3135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 3136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", 3139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 3140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent = playDtmfEvent; 3142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); 3143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetDtmfPlayoutStatus(bool enable) 3149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetDtmfPlayoutStatus()"); 3152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetDtmfPlayoutStatus(enable) != 0) 3153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 3156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetDtmfPlayoutStatus() failed to set Dtmf playout"); 3157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 3163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DtmfPlayoutStatus() const 3164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _audioCodingModule.DtmfPlayoutStatus(); 3166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendTelephoneEventPayloadType(unsigned char type) 3170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendTelephoneEventPayloadType()"); 3173f81f9f8c2a18fb20ee60406ece45ff3210367ff9andrew@webrtc.org if (type > 127) 3174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTelephoneEventPayloadType() invalid type"); 3178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 31801da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org CodecInst codec; 31811da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.plfreq = 8000; 31821da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.pltype = type; 31831da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org memcpy(codec.plname, "telephone-event", 16); 31842853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 3185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 31864392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 31874392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { 31884392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _engineStatisticsPtr->SetLastError( 31894392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 31904392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "SetSendTelephoneEventPayloadType() failed to register send" 31914392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "payload type"); 31924392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org return -1; 31934392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org } 3194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTelephoneEventPayloadType = type; 3196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendTelephoneEventPayloadType(unsigned char& type) 3201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendTelephoneEventPayloadType()"); 3204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com type = _sendTelephoneEventPayloadType; 3205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTelephoneEventPayloadType() => type=%u", type); 3208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateRxVadDetection(AudioFrame& audioFrame) 3213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection()"); 3216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int vadDecision = 1; 3218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 321963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; 3220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) 3222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OnRxVadDetected(vadDecision); 3224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _oldVadDecision = vadDecision; 3225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection() => vadDecision=%d", 3229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com vadDecision); 3230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRxVadObserver(VoERxVadCallback &observer) 3235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRxVadObserver()"); 32389a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 3241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRxVadObserver() observer already enabled"); 3245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = &observer; 3248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = true; 3249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRxVadObserver() 3254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRxVadObserver()"); 32579a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rxVadObserverPtr) 3260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRxVadObserver() observer already disabled"); 3264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = NULL; 3267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = false; 3268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::VoiceActivityIndicator(int &activity) 3273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com activity = _sendFrameType; 3275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::VoiceActivityIndicator(indicator=%d)", activity); 3278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_AGC 3282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 32849213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcStatus(bool enable, AgcModes mode) 3285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcStatus(enable=%d, mode=%d)", 3288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 3289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode(GainControl::kFixedDigital); 3291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 3292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcDefault: 3294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kAdaptiveDigital; 3295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcUnchanged: 3297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = _rxAudioProcessingModulePtr->gain_control()->mode(); 3298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcFixedDigital: 3300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kFixedDigital; 3301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcAdaptiveDigital: 3303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode =GainControl::kAdaptiveDigital; 3304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 3306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() invalid Agc mode"); 3309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_mode(agcMode) != 0) 3313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc mode"); 3317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->Enable(enable) != 0) 3320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 3324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled = enable; 3328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 3329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcStatus(bool& enabled, AgcModes& mode) 3335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcStatus(enable=?, mode=?)"); 3338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = _rxAudioProcessingModulePtr->gain_control()->is_enabled(); 3340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode = 3341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->mode(); 3342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 3344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (agcMode) 3346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kFixedDigital: 3348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcFixedDigital; 3349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kAdaptiveDigital: 3351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcAdaptiveDigital; 3352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 3354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxAgcStatus() invalid Agc mode"); 3357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 33649213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcConfig(AgcConfig config) 3365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcConfig()"); 3368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_target_level_dbfs( 3370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv) != 0) 3371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set target peak |level|" 3375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "(or envelope) of the Agc"); 3376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_compression_gain_db( 3379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB) != 0) 3380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set the range in |gain| the" 3384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " digital compression stage may apply"); 3385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->enable_limiter( 3388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable) != 0) 3389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set hard limiter to the signal"); 3393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcConfig(AgcConfig& config) 3401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcConfig(config=%?)"); 3404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv = 3406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->target_level_dbfs(); 3407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB = 3408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->compression_gain_db(); 3409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable = 3410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->is_limiter_enabled(); 3411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), "GetRxAgcConfig() => " 3414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "targetLeveldBOv=%u, digitalCompressionGaindB=%u," 3415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " limiterEnable=%d", 3416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv, 3417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB, 3418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable); 3419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC 3424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_NR 3426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 34289213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxNsStatus(bool enable, NsModes mode) 3429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxNsStatus(enable=%d, mode=%d)", 3432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 3433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level nsLevel( 3435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE); 3436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 3437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsDefault: 3440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = (NoiseSuppression::Level) 3441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE; 3442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsUnchanged: 3444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = _rxAudioProcessingModulePtr->noise_suppression()->level(); 3445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsConference: 3447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 3448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsLowSuppression: 3450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kLow; 3451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsModerateSuppression: 3453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kModerate; 3454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsHighSuppression: 3456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 3457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsVeryHighSuppression: 3459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kVeryHigh; 3460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->set_level(nsLevel) 3464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 3465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Ns level"); 3469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->Enable(enable) != 0) 3472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 3475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 3476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxNsIsEnabled = enable; 3480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 3481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxNsStatus(bool& enabled, NsModes& mode) 3487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxNsStatus(enable=?, mode=?)"); 3490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = 3492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->noise_suppression()->is_enabled(); 3493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level ncLevel = 3494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->noise_suppression()->level(); 3495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 3497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (ncLevel) 3499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kLow: 3501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsLowSuppression; 3502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kModerate: 3504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsModerateSuppression; 3505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kHigh: 3507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsHighSuppression; 3508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kVeryHigh: 3510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsVeryHighSuppression; 3511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxNsStatus() => enabled=%d, mode=%d", enabled, mode); 3517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_NR 3521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRTPObserver(VoERTPObserver& observer) 3524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRTPObserver()"); 35279a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 3530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRTPObserver() observer already enabled"); 3534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr = &observer; 3538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserver = true; 3539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRTPObserver() 3545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRTPObserver()"); 35489a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rtpObserverPtr) 3551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRTPObserver() observer already disabled"); 3555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserver = false; 3559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr = NULL; 3560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRTCPObserver(VoERTCPObserver& observer) 3566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRTCPObserver()"); 35699a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserverPtr) 3572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRTCPObserver() observer already enabled"); 3576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr = &observer; 3580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserver = true; 3581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRTCPObserver() 3587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRTCPObserver()"); 35909a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rtcpObserverPtr) 3593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRTCPObserver() observer already disabled"); 3597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserver = false; 3601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr = NULL; 3602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetLocalSSRC(unsigned int ssrc) 3608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetLocalSSRC()"); 3611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 3612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_SENDING, kTraceError, 3615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() already sending"); 3616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 36182853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSSRC(ssrc) != 0) 3619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() failed to set SSRC"); 3623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetLocalSSRC(unsigned int& ssrc) 3630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 36312853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->SSRC(); 3632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalSSRC() => ssrc=%lu", ssrc); 3635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteSSRC(unsigned int& ssrc) 3640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 36412853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->RemoteSSRC(); 3642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteSSRC() => ssrc=%lu", ssrc); 3645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteCSRCs(unsigned int arrCSRC[15]) 3650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (arrCSRC == NULL) 3652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() invalid array argument"); 3656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 36586141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t arrOfCSRC[kRtpCsrcSize]; 36596141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t CSRCs(0); 36602853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org CSRCs = _rtpRtcpModule->CSRCs(arrOfCSRC); 3661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CSRCs > 0) 3662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 36636141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org memcpy(arrCSRC, arrOfCSRC, CSRCs * sizeof(uint32_t)); 3664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int i = 0; i < (int) CSRCs; i++) 3665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() => arrCSRC[%d]=%lu", i, arrCSRC[i]); 3669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 3671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() => list is empty!"); 3675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return CSRCs; 3677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTPAudioLevelIndicationStatus(bool enable, unsigned char ID) 3681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3682755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc.get() == NULL) 3683755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 3684755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc.reset(AudioProcessing::Create(VoEModuleId(_instanceId, 3685755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _channelId))); 3686755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc.get() == NULL) 3687755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 3688755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_NO_MEMORY, kTraceCritical, 3689755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Failed to create AudioProcessing"); 3690755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 3691755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 3692755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 3693755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 3694755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc->level_estimator()->Enable(enable) != 3695755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org AudioProcessing::kNoError) 3696755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 3697755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_APM_ERROR, kTraceWarning, 3698755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Failed to enable AudioProcessing::level_estimator()"); 3699755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 3700755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 3701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _includeAudioLevelIndication = enable; 37022853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->SetRTPAudioLevelIndicationStatus(enable, ID); 3703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPAudioLevelIndicationStatus(bool& enabled, unsigned char& ID) 3706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPAudioLevelIndicationStatus() => enabled=%d, ID=%u", 3710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, ID); 37112853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->GetRTPAudioLevelIndicationStatus(enabled, ID); 3712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCPStatus(bool enable) 3716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCPStatus()"); 37192853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPStatus(enable ? 3720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRtcpCompound : kRtcpOff) != 0) 3721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCPStatus() failed to set RTCP status"); 3725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCPStatus(bool& enabled) 3732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 37332853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 3734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (method != kRtcpOff); 3735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCPStatus() => enabled=%d", enabled); 3738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCP_CNAME(const char cName[256]) 3743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCP_CNAME()"); 37462853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetCNAME(cName) != 0) 3747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCP_CNAME() failed to set RTCP CNAME"); 3751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCP_CNAME(char cName[256]) 3758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 37592853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->CNAME(cName) != 0) 3760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCP_CNAME() failed to retrieve RTCP CNAME"); 3764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCP_CNAME() => cName=%s", cName); 3769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCP_CNAME(char cName[256]) 3774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cName == NULL) 3776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); 3780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3782813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char cname[RTCP_CNAME_SIZE]; 37836141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 37842853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) 3785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_CNAME, kTraceError, 3788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); 3789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(cName, cname); 3792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() => cName=%s", cName); 3795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCPData( 3800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPHigh, 3801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPLow, 3802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& timestamp, 3803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& playoutTimestamp, 3804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int* jitter, 3805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short* fractionLost) 3806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Information from sender info in received Sender Reports 3808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPSenderInfo senderInfo; 38102853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) 3811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3814fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRemoteRTCPData() failed to retrieve sender info for remote " 3815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "side"); 3816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We only utilize 12 out of 20 bytes in the sender info (ignores packet 3820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and octet count) 3821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh = senderInfo.NTPseconds; 3822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPLow = senderInfo.NTPfraction; 3823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp = senderInfo.RTPtimeStamp; 3824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " 3828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "timestamp=%lu", 3829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh, NTPLow, timestamp); 3830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Locally derived information 3832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This value is updated on each incoming RTCP packet (0 when no packet 3834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has been received) 38351de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playoutTimestamp = playout_timestamp_rtcp_; 3836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => playoutTimestamp=%lu", 38401de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_); 3841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL != jitter || NULL != fractionLost) 3843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3844ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Get all RTCP receiver report blocks that have been received on this 3845ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // channel. If we receive RTP packets from a remote source we know the 3846ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // remote SSRC and use the report block from him. 3847ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Otherwise use the first report block. 3848ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock> remote_stats; 38492853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || 3850ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remote_stats.empty()) { 3851ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3852ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org VoEId(_instanceId, _channelId), 3853ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org "GetRemoteRTCPData() failed to measure statistics due" 3854ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org " to lack of received RTP and/or RTCP packets"); 3855ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org return -1; 3856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3857ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 38586141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 3859ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin(); 3860ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org for (; it != remote_stats.end(); ++it) { 3861ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it->remoteSSRC == remoteSSRC) 3862ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org break; 3863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3864ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 3865ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it == remote_stats.end()) { 3866ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // If we have not received any RTCP packets from this SSRC it probably 3867ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // means that we have not received any RTP packets. 3868ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Use the first received report block instead. 3869ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org it = remote_stats.begin(); 3870ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remoteSSRC = it->remoteSSRC; 3871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3872ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 387379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (jitter) { 387479af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *jitter = it->jitter; 387579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 387679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 387779af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => jitter = %lu", *jitter); 387879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 3879ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 388079af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (fractionLost) { 388179af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost = it->fractionLost; 388279af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 388379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 388479af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => fractionLost = %lu", 388579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost); 388679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 3887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 38929213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SendApplicationDefinedRTCPPacket(unsigned char subType, 3893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int name, 3894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* data, 3895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short dataLengthInBytes) 3896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendApplicationDefinedRTCPPacket()"); 3899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_sending) 3900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 3903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() not sending"); 3904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL == data) 3907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid data value"); 3911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (dataLengthInBytes % 4 != 0) 3914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid length value"); 3918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 39202853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod status = _rtpRtcpModule->RTCP(); 3921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status == kRtcpOff) 3922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTCP_ERROR, kTraceError, 3925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() RTCP is disabled"); 3926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create and schedule the RTCP APP packet for transmission 39302853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPApplicationSpecificData( 3931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 3932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 3933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const unsigned char*) data, 3934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataLengthInBytes) != 0) 3935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_ERROR, kTraceError, 3938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); 3939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics( 3946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& averageJitterMs, 3947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& maxJitterMs, 3948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& discardedPackets) 3949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 39506141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t fraction_lost(0); 39516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t cum_lost(0); 39526141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t ext_max(0); 39536141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t jitter(0); 39546141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t max_jitter(0); 3955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 3957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 39582853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 3959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &cum_lost, 3960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ext_max, 3961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &jitter, 3962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &max_jitter) != 0) 3963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 3966fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to read RTP statistics from the " 3967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP/RTCP module"); 3968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39706141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const int32_t playoutFrequency = 3971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.PlayoutFrequency(); 3972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (playoutFrequency > 0) 3973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale RTP statistics given the current playout frequency 3975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxJitterMs = max_jitter / (playoutFrequency / 1000); 3976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs = jitter / (playoutFrequency / 1000); 3977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com discardedPackets = _numberOfDiscardedPackets; 3980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => averageJitterMs = %lu, maxJitterMs = %lu," 3984fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " discardedPackets = %lu)", 3985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs, maxJitterMs, discardedPackets); 3986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39898a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPSenderInfo(SenderInfo* sender_info) { 39908a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (sender_info == NULL) { 39918a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 39928a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPSenderInfo() invalid sender_info."); 39938a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 39948a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 39958a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 39968a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the sender info from the latest received RTCP Sender Report. 39978a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org RTCPSenderInfo rtcp_sender_info; 39988a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_sender_info) != 0) { 39998a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 40008a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPSenderInfo() failed to read RTCP SR sender info."); 40018a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 40028a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 40038a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 40048a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->NTP_timestamp_high = rtcp_sender_info.NTPseconds; 40058a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->NTP_timestamp_low = rtcp_sender_info.NTPfraction; 40068a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->RTP_timestamp = rtcp_sender_info.RTPtimeStamp; 40078a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->sender_packet_count = rtcp_sender_info.sendPacketCount; 40088a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->sender_octet_count = rtcp_sender_info.sendOctetCount; 40098a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 40108a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 40118a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 40128a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPReportBlocks( 40138a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<ReportBlock>* report_blocks) { 40148a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (report_blocks == NULL) { 40158a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 40168a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlock()s invalid report_blocks."); 40178a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 40188a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 40198a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 40208a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the report blocks from the latest received RTCP Sender or Receiver 40218a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Report. Each element in the vector contains the sender's SSRC and a 40228a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // report block according to RFC 3550. 40238a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock> rtcp_report_blocks; 40248a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) { 40258a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 40268a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlocks() failed to read RTCP SR/RR report block."); 40278a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 40288a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 40298a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 40308a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (rtcp_report_blocks.empty()) 40318a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 40328a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 40338a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin(); 40348a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org for (; it != rtcp_report_blocks.end(); ++it) { 40358a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org ReportBlock report_block; 40368a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.sender_SSRC = it->remoteSSRC; 40378a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.source_SSRC = it->sourceSSRC; 40388a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.fraction_lost = it->fractionLost; 40398a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.cumulative_num_packets_lost = it->cumulativeLost; 40408a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.extended_highest_sequence_number = it->extendedHighSeqNum; 40418a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.interarrival_jitter = it->jitter; 40428a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.last_SR_timestamp = it->lastSR; 40438a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.delay_since_last_SR = it->delaySinceLastSR; 40448a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_blocks->push_back(report_block); 40458a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 40468a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 40478a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 40488a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 4049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics(CallStatistics& stats) 4051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 40526141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t fraction_lost(0); 40536141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t cum_lost(0); 40546141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t ext_max(0); 40556141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t jitter(0); 40566141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t max_jitter(0); 4057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part one of the final structure (four values) 4059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 4061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 40622853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 4063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &cum_lost, 4064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ext_max, 4065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &jitter, 4066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &max_jitter) != 0) 4067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 4070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to read RTP statistics from the " 4071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP/RTCP module"); 4072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost = fraction_lost; 4075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.cumulativeLost = cum_lost; 4076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.extendedMax = ext_max; 4077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples = jitter; 4078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => fractionLost=%lu, cumulativeLost=%lu," 4082fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " extendedMax=%lu, jitterSamples=%li)", 4083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost, stats.cumulativeLost, stats.extendedMax, 4084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples); 4085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part two of the final structure (one value) 4087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t RTT(0); 40892853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 4090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (method == kRtcpOff) 4091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4094fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() RTCP is disabled => valid RTT " 4095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "measurements cannot be retrieved"); 4096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 4097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The remote SSRC will be zero if no RTP packet has been received. 40996141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 4100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (remoteSSRC > 0) 4101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 41026141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t avgRTT(0); 41036141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t maxRTT(0); 41046141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t minRTT(0); 4105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41062853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT, &maxRTT) 4107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 4108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4111fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to retrieve RTT from " 4112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP module"); 4113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 4115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4118fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to measure RTT since no " 4119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP packets have been received yet"); 4120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.rttMs = static_cast<int> (RTT); 4124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => rttMs=%d", stats.rttMs); 4128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part three of the final structure (four values) 4130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41316141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t bytesSent(0); 41326141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsSent(0); 41336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t bytesReceived(0); 41346141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsReceived(0); 4135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41362853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DataCountersRTP(&bytesSent, 4137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &packetsSent, 4138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &bytesReceived, 4139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &packetsReceived) != 0) 4140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to retrieve RTP datacounters =>" 4144fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " output will not be complete"); 4145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent = bytesSent; 4148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsSent = packetsSent; 4149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesReceived = bytesReceived; 4150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived = packetsReceived; 4151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => bytesSent=%d, packetsSent=%d," 4155fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " bytesReceived=%d, packetsReceived=%d)", 4156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent, stats.packetsSent, stats.bytesReceived, 4157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived); 4158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 416242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetFECStatus(bool enable, int redPayloadtype) { 416342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 416442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "Channel::SetFECStatus()"); 416542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 41668c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (enable) { 41678c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (redPayloadtype < 0 || redPayloadtype > 127) { 41688c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 41698c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_PLTYPE_ERROR, kTraceError, 41708c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org "SetFECStatus() invalid RED payload type"); 41718c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 41728c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 41738c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org 41748c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (SetRedPayloadType(redPayloadtype) < 0) { 41758c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 41768c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 41778c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 41788c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 41798c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 418042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 41812cf22a6abce2d38e673505a4cfd5624a3710b5cdperkj@webrtc.org 418242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.SetFECStatus(enable) != 0) { 418342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 418442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 418542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetFECStatus() failed to set FEC state in the ACM"); 418642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 418742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 418842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 4189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetFECStatus(bool& enabled, int& redPayloadtype) 4193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = _audioCodingModule.FECStatus(); 4195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 4196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 41976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(0); 41982853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendREDPayloadType(payloadType) != 0) 4199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() failed to retrieve RED PT from RTP/RTCP " 4203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 4204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() => enabled=%d, redPayloadtype=%d", 4209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, redPayloadtype); 4210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() => enabled=%d", enabled); 4215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartRTPDump(const char fileNameUTF8[1024], 4220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTPDirections direction) 4221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRTPDump()"); 4224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 4225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() invalid RTP direction"); 4229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 4232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 4233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 4234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 4236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->IsActive()) 4239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpDumpPtr->Stop(); 4241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->Start(fileNameUTF8) != 0) 4243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 4246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() failed to create file"); 4247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopRTPDump(RTPDirections direction) 4254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRTPDump()"); 4257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 4258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRTPDump() invalid RTP direction"); 4262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 4265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 4266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 4267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 4269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!rtpDumpPtr->IsActive()) 4272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->Stop(); 4276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 4279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RTPDumpIsActive(RTPDirections direction) 4280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && 4282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (direction != kRtpOutgoing)) 4283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTPDumpIsActive() invalid RTP direction"); 4287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 4288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 4290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 4291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->IsActive(); 4292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertExtraRTPPacket(unsigned char payloadType, 4296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool markerBit, 4297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* payloadData, 4298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short payloadSize) 4299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::InsertExtraRTPPacket()"); 4302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (payloadType > 127) 4303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_PLTYPE, kTraceError, 4306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload type"); 4307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (payloadData == NULL) 4310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload data"); 4314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 43162853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (payloadSize > _rtpRtcpModule->MaxDataPayloadLength()) 4317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload size"); 4321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_sending) 4324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 4327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() not sending"); 4328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create extra RTP packet by calling RtpRtcp::SendOutgoingData(). 4332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Transport::SendPacket() will be called by the module when the RTP packet 4333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // is created. 4334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The call to SendOutgoingData() does *not* modify the timestamp and 4335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // payloadtype to ensure that the RTP module generates a valid RTP packet 4336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (user might utilize a non-registered payload type). 4337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The marker bit and payload type will be replaced just before the actual 4338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // transmission, i.e., the actual modification is done *after* the RTP 4339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // module has delivered its RTP packet back to the VoE. 4340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will use the stored values above when the packet is modified 4341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (see Channel::SendPacket()). 4342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraPayloadType = payloadType; 4344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraMarkerBit = markerBit; 4345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket = true; 4346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43472853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendOutgoingData(kAudioFrameSpeech, 4348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType, 4349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp, 4350ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // Leaving the time when this frame was 4351ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // received from the capture device as 4352ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // undefined for voice for now. 4353ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org -1, 43546141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (const uint8_t*) payloadData, 4355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize) != 0) 4356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() failed to send extra RTP packet"); 4360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43666141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 4367755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.orgChannel::Demultiplex(const AudioFrame& audioFrame) 4368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4370755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Channel::Demultiplex()"); 4371ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.CopyFrom(audioFrame); 437263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 4373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43766141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 43770b0665acc1464d68e878f203bbc8772a0e32402dxians@google.comChannel::PrepareEncodeAndSend(int mixingFrequency) 4378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend()"); 4381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 438263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 4383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 4385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend() invalid audio frame"); 4386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 4390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MixOrReplaceAudioWithFile(mixingFrequency); 4392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mute) 4395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Mute(_audioFrame); 4397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMedia) 4400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 44019a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 440263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (_audioFrame.num_channels_ == 2); 4403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 4404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr->Process( 4406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 4407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRecordingPerChannel, 44086141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (int16_t*)_audioFrame.data_, 440963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.samples_per_channel_, 441063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.sample_rate_hz_, 4411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 4412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com InsertInbandDtmfTone(); 4416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4417755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_includeAudioLevelIndication) 4418755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 4419755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org assert(_rtpAudioProc.get() != NULL); 4420755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 4421755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org // Check if settings need to be updated. 442263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->sample_rate_hz() != _audioFrame.sample_rate_hz_) 4423755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 442463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->set_sample_rate_hz(_audioFrame.sample_rate_hz_) != 4425755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org AudioProcessing::kNoError) 4426755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 4427755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4428755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org VoEId(_instanceId, _channelId), 4429755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Error setting AudioProcessing sample rate"); 4430755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 4431755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 4432755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 4433755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 443463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->num_input_channels() != _audioFrame.num_channels_) 4435755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 443663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->set_num_channels(_audioFrame.num_channels_, 443763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.num_channels_) 4438755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org != AudioProcessing::kNoError) 4439755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 4440755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4441755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org VoEId(_instanceId, _channelId), 4442755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Error setting AudioProcessing channels"); 4443755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 4444755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 4445755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 4446755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 4447755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org // Performs level analysis only; does not affect the signal. 4448755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc->ProcessStream(&_audioFrame); 4449755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 4450755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 4451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 44546141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 4455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EncodeAndSend() 4456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend()"); 4459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 446063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.num_channels_ <= 2); 446163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 4462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 4464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() invalid audio frame"); 4465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 446863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 4469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. 4471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The ACM resamples internally. 447363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.timestamp_ = _timeStamp; 4474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.Add10MsData((AudioFrame&)_audioFrame) != 0) 4475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 4477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() ACM encoding failed"); 4478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 448163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 4482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Encode if complete frame is ready 4484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call will trigger AudioPacketizationCallback::SendData if encoding 4486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // is done and payload is ready for packetization and transmission. 4487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _audioCodingModule.Process(); 4488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::RegisterExternalMediaProcessing( 4491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessingTypes type, 4492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEMediaProcess& processObject) 4493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing()"); 4496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 44979a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 4500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 4502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 4506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 4507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = &processObject; 4510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = true; 4511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 4513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 4515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 4519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 4520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = &processObject; 4523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia = true; 4524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) 4529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing()"); 4532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 45339a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 4536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputExternalMediaCallbackPtr) 4538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 4542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already disabled"); 4543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = false; 4546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = NULL; 4547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 4549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputExternalMediaCallbackPtr) 4551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 4555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "input external media already disabled"); 4556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia = false; 4559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = NULL; 4560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 45651b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.comint Channel::SetExternalMixing(bool enabled) { 45661b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 45671b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing(enabled=%d)", enabled); 45681b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 45691b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_playing) 45701b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 45711b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 45721b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_INVALID_OPERATION, kTraceError, 45731b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing() " 45741b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "external mixing cannot be changed while playing."); 45751b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 45761b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 45771b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 45781b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing = enabled; 45791b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 45801b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return 0; 45811b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com} 45821b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 4583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ResetRTCPStatistics() 4585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ResetRTCPStatistics()"); 45886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t remoteSSRC(0); 45892853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 45902853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->ResetRTT(remoteSSRC); 4591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRoundTripTimeSummary(StatVal& delaysMs) const 4595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary()"); 4598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Override default module outputs for the case when RTCP is disabled. 4599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is done to ensure that we are backward compatible with the 4600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // VoiceEngine where we did not use RTP/RTCP module. 46012853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (!_rtpRtcpModule->RTCP()) 4602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = -1; 4604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.max = -1; 4605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.average = -1; 4606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 4607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary() RTCP is disabled =>" 4608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " valid RTT measurements cannot be retrieved"); 4609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 46126141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t remoteSSRC; 46136141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t RTT; 46146141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t avgRTT; 46156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t maxRTT; 46166141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t minRTT; 4617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The remote SSRC will be zero if no RTP packet has been received. 46182853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 4619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (remoteSSRC == 0) 4620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 4622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary() unable to measure RTT" 4623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " since no RTP packet has been received yet"); 4624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Retrieve RTT statistics from the RTP/RTCP module for the specified 4627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // channel and SSRC. The SSRC is required to parse out the correct source 4628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in conference scenarios. 46292853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT,&maxRTT) != 0) 4630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 4632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRoundTripTimeSummary unable to retrieve RTT values" 4633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " from the RTCP layer"); 4634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = -1; delaysMs.max = -1; delaysMs.average = -1; 4635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = minRTT; 4639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.max = maxRTT; 4640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.average = avgRTT; 4641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetworkStatistics(NetworkStatistics& stats) 4647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetworkStatistics()"); 46507a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org ACMNetworkStatistics acm_stats; 46517a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org int return_value = _audioCodingModule.NetworkStatistics(&acm_stats); 46527a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if (return_value >= 0) { 46537a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org memcpy(&stats, &acm_stats, sizeof(NetworkStatistics)); 46547a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org } 46557a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org return return_value; 4656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 46581de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgbool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, 46591de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org int* playout_buffer_delay_ms) const { 46601de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_average_jitter_buffer_delay_us == 0) { 4661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 46621de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate() no valid estimate."); 46631de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return false; 46641de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 46651de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 + 46661de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _recPacketDelayMs; 46671de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *playout_buffer_delay_ms = playout_delay_ms_; 46681de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 46691de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate()"); 46701de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return true; 4671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 46736388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgint Channel::SetInitialPlayoutDelay(int delay_ms) 46746388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org{ 46756388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 46766388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "Channel::SetInitialPlayoutDelay()"); 46776388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) || 46786388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs)) 46796388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 46806388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 46816388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 46826388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() invalid min delay"); 46836388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 46846388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 46856388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org if (_audioCodingModule.SetInitialPlayoutDelay(delay_ms) != 0) 46866388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 46876388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 46886388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 46896388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() failed to set min playout delay"); 46906388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 46916388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 46926388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return 0; 46936388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org} 46946388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 46956388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 4696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMinimumPlayoutDelay(int delayMs) 4698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMinimumPlayoutDelay()"); 4701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || 4702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) 4703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() invalid min delay"); 4707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetMinimumPlayoutDelay(delayMs) != 0) 4710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 4713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() failed to set min playout delay"); 4714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 47191de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgvoid Channel::UpdatePlayoutTimestamp(bool rtcp) { 47201de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint32_t playout_timestamp = 0; 47211de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47221de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_audioCodingModule.PlayoutTimestamp(&playout_timestamp) == -1) { 47231de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 47241de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePlayoutTimestamp() failed to read playout" 47251de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org " timestamp from the ACM"); 47261de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 47271de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 47281de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "UpdatePlayoutTimestamp() failed to retrieve timestamp"); 47291de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 47301de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 47311de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47321de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t delay_ms = 0; 47331de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) { 47341de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 47351de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePlayoutTimestamp() failed to read playout" 47361de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org " delay from the ADM"); 47371de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 47381de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 47391de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "UpdatePlayoutTimestamp() failed to retrieve playout delay"); 47401de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 47411de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 47421de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47431de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org int32_t playout_frequency = _audioCodingModule.PlayoutFrequency(); 47441de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org CodecInst current_recive_codec; 47451de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_audioCodingModule.ReceiveCodec(¤t_recive_codec) == 0) { 47461de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (STR_CASE_CMP("G722", current_recive_codec.plname) == 0) { 47471de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_frequency = 8000; 47481de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } else if (STR_CASE_CMP("opus", current_recive_codec.plname) == 0) { 47491de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_frequency = 48000; 4750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 47511de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 47521de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47531de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Remove the playout delay. 47541de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp -= (delay_ms * (playout_frequency / 1000)); 47551de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47561de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 47571de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu", 47581de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp); 47591de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47601de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (rtcp) { 47611de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_ = playout_timestamp; 47621de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } else { 47631de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtp_ = playout_timestamp; 47641de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 47651de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_delay_ms_ = delay_ms; 47661de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org} 47671de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 47681de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgint Channel::GetPlayoutTimestamp(unsigned int& timestamp) { 47691de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 47701de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetPlayoutTimestamp()"); 47711de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (playout_timestamp_rtp_ == 0) { 47721de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 47731de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 47741de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() failed to retrieve timestamp"); 47751de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return -1; 47761de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 47771de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org timestamp = playout_timestamp_rtp_; 47781de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 47791de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VoEId(_instanceId,_channelId), 47801de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() => timestamp=%u", timestamp); 47811de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return 0; 4782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetInitTimestamp(unsigned int timestamp) 4786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitTimestamp()"); 4789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 4790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, "SetInitTimestamp() already sending"); 4793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 47952853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetStartTimestamp(timestamp) != 0) 4796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitTimestamp() failed to set timestamp"); 4800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetInitSequenceNumber(short sequenceNumber) 4807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitSequenceNumber()"); 4810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 4811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 4814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitSequenceNumber() already sending"); 4815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 48172853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSequenceNumber(sequenceNumber) != 0) 4818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitSequenceNumber() failed to set sequence number"); 4822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRtpRtcp(RtpRtcp* &rtpRtcpModule) const 4829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRtpRtcp()"); 48322853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org rtpRtcpModule = _rtpRtcpModule.get(); 4833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4836e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use 4837e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// a shared helper. 48386141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 48399213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::MixOrReplaceAudioWithFile(int mixingFrequency) 4840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 48416141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org scoped_array<int16_t> fileBuffer(new int16_t[640]); 4842e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 4843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 48459a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 4846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 4848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() fileplayer" 4852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " doesnt exist"); 4853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4856d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 4857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 4858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 4859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file mixing " 4863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 4864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fileSamples == 0) 4867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file is ended"); 4871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 487563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == fileSamples); 4876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mixFileWithMicrophone) 4878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4879d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 4880d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 488163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org Utility::MixWithSat(_audioFrame.data_, 4882e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org _audioFrame.num_channels_, 4883d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 4884d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org 1, 4885e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples); 4886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4889d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Replace ACM audio with file. 4890d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 4891d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 4892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioFrame.UpdateFrame(_channelId, 4893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -1, 4894d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 4895e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples, 4896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency, 4897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kNormalSpeech, 4898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kVadUnknown, 4899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 4900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 49056141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 4906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::MixAudioWithFile(AudioFrame& audioFrame, 49079213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int mixingFrequency) 4908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(mixingFrequency <= 32000); 4910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 49116141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org scoped_array<int16_t> fileBuffer(new int16_t[640]); 4912e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 4913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 49159a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 4916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 4918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 4922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We should get the frequency we ask for. 4926d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 4927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 4928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 4929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 4933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 493763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.samples_per_channel_ == fileSamples) 4938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4939d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 4940d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 494163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org Utility::MixWithSat(audioFrame.data_, 4942e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org audioFrame.num_channels_, 4943d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 4944d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org 1, 4945e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples); 4946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 495063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org "Channel::MixAudioWithFile() samples_per_channel_(%d) != " 4951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "fileSamples(%d)", 495263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, fileSamples); 4953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertInbandDtmfTone() 4961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4962af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Check if we should start a new tone. 4963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfQueue.PendingDtmf() && 4964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !_inbandDtmfGenerator.IsAddingTone() && 4965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.DelaySinceLastTone() > 4966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kMinTelephoneEventSeparationMs) 4967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 49686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t eventCode(0); 49696141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t lengthMs(0); 49706141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t attenuationDb(0); 4971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); 4973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); 4974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playInbandDtmfEvent) 4975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add tone to output mixer using a reduced length to minimize 4977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // risk of echo. 4978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, 4979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb); 4980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.IsAddingTone()) 4984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 49856141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t frequency(0); 4986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.GetSampleRate(frequency); 4987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 498863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (frequency != _audioFrame.sample_rate_hz_) 4989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update sample rate of Dtmf tone since the mixing frequency 4991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has changed. 4992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.SetSampleRate( 49936141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t) (_audioFrame.sample_rate_hz_)); 4994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset the tone to be added taking the new sample rate into 4995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // account. 4996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.ResetTone(); 4997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4998ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 49996141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t toneBuffer[320]; 50006141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t toneSamples(0); 5001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms tone segment and set time since last tone to zero 5002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) 5003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() inserting Dtmf failed"); 5007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5010af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Replace mixed audio with DTMF tone. 5011ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org for (int sample = 0; 501263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org sample < _audioFrame.samples_per_channel_; 5013af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org sample++) 5014af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 5015ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org for (int channel = 0; 5016ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org channel < _audioFrame.num_channels_; 5017af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org channel++) 5018af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 5019ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org const int index = sample * _audioFrame.num_channels_ + channel; 5020ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.data_[index] = toneBuffer[sample]; 5021af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 5022af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 5023ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 502463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == toneSamples); 5025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 5026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add 10ms to "delay-since-last-tone" counter 5028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.UpdateDelaySinceLastTone(); 5029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 5034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ResetDeadOrAliveCounters() 5035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections = 0; 5037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections = 0; 5038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 5041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateDeadOrAliveCounters(bool alive) 5042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (alive) 5044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections++; 5045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 5046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections++; 5047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetDeadOrAliveCounters(int& countDead, int& countAlive) const 5051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enabled; 50536141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t timeSec; 5054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50552853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, timeSec); 5056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!enabled) 5057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (-1); 5058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com countDead = static_cast<int> (_countDeadDetections); 5060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com countAlive = static_cast<int> (_countAliveDetections); 5061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50646141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 5065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendPacketRaw(const void *data, int len, bool RTCP) 5066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 5068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!RTCP) 5072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendPacket(_channelId, data, len); 5074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 5076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendRTCPPacket(_channelId, data, len); 5078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50811de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org// Called for incoming RTP packets after successful RTP header parsing. 50821de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgvoid Channel::UpdatePacketDelay(uint32_t rtp_timestamp, 50831de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t sequence_number) { 50841de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 50851de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 50861de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org rtp_timestamp, sequence_number); 5087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50881de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Get frequency of last received payload 50891de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org int rtp_receive_frequency = _audioCodingModule.ReceiveFrequency(); 5090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 50911de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org CodecInst current_receive_codec; 50921de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_audioCodingModule.ReceiveCodec(¤t_receive_codec) != 0) { 50931de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 50941de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 5095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5096e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org // Update the least required delay. 5097e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org least_required_delay_ms_ = _audioCodingModule.LeastRequiredDelayMs(); 5098e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org 50991de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (STR_CASE_CMP("G722", current_receive_codec.plname) == 0) { 51001de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Even though the actual sampling rate for G.722 audio is 51011de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // 16,000 Hz, the RTP clock rate for the G722 payload format is 51021de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // 8,000 Hz because that value was erroneously assigned in 51031de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // RFC 1890 and must remain unchanged for backward compatibility. 51041de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org rtp_receive_frequency = 8000; 51051de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } else if (STR_CASE_CMP("opus", current_receive_codec.plname) == 0) { 51061de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // We are resampling Opus internally to 32,000 Hz until all our 51071de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // DSP routines can operate at 48,000 Hz, but the RTP clock 51081de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // rate for the Opus payload format is standardized to 48,000 Hz, 51091de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // because that is the maximum supported decoding sampling rate. 51101de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org rtp_receive_frequency = 48000; 51111de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 5112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51131de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // playout_timestamp_rtp_ updated in UpdatePlayoutTimestamp for every incoming 51141de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // packet. 51151de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint32_t timestamp_diff_ms = (rtp_timestamp - playout_timestamp_rtp_) / 51161de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org (rtp_receive_frequency / 1000); 5117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51181de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) / 51191de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org (rtp_receive_frequency / 1000); 5120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51211de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _previousTimestamp = rtp_timestamp; 5122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51231de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) { 51241de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org timestamp_diff_ms = 0; 51251de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 51261de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 51271de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (timestamp_diff_ms == 0) return; 51281de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 51291de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (packet_delay_ms >= 10 && packet_delay_ms <= 60) { 51301de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _recPacketDelayMs = packet_delay_ms; 51311de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 51321de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 51331de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_average_jitter_buffer_delay_us == 0) { 51341de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000; 51351de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 51361de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 51371de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 51381de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Filter average delay value using exponential filter (alpha is 51391de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces 51401de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // risk of rounding error) and compensate for it in GetDelayEstimate() 51411de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // later. 51421de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 + 51431de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 1000 * timestamp_diff_ms + 500) / 8; 5144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 5147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterReceiveCodecsToRTPModule() 5148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule()"); 5151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 51546141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 5155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 5157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 51597a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org if ((_audioCodingModule.Codec(idx, &codec) == -1) || 51602853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 5161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 5163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 5164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 5165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() unable" 5167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " to register %s (%d/%d/%d/%d) to RTP/RTCP receiver", 5168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 5169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 5170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 5172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 5174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceInfo, 5175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 5176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() %s " 5178fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "(%d/%d/%d/%d) has been added to the RTP/RTCP " 5179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "receiver", 5180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 5181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 5182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 518650419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgint Channel::ApmProcessRx(AudioFrame& frame) { 518750419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org AudioProcessing* audioproc = _rxAudioProcessingModulePtr; 518850419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org // Register the (possibly new) frame parameters. 518950419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->set_sample_rate_hz(frame.sample_rate_hz_) != 0) { 5190655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR1(LS_WARNING, set_sample_rate_hz, frame.sample_rate_hz_); 519150419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 519250419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->set_num_channels(frame.num_channels_, 519350419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org frame.num_channels_) != 0) { 5194655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR1(LS_WARNING, set_num_channels, frame.num_channels_); 519550419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 519650419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->ProcessStream(&frame) != 0) { 5197655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR0(LS_WARNING, ProcessStream); 519850419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 519950419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org return 0; 5200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 520242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetSecondarySendCodec(const CodecInst& codec, 520342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org int red_payload_type) { 52048c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org // Sanity check for payload type. 52058c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (red_payload_type < 0 || red_payload_type > 127) { 52068c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 52078c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_PLTYPE_ERROR, kTraceError, 52088c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org "SetRedPayloadType() invalid RED payload type"); 52098c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 52108c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 52118c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org 521242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (SetRedPayloadType(red_payload_type) < 0) { 521342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 521442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 521542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 521642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 521742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 521842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.RegisterSecondarySendCodec(codec) < 0) { 521942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 522042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 522142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetSecondarySendCodec() Failed to register secondary send codec in " 522242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "ACM"); 522342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 522442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 522542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 522642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 522742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 522842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 522942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgvoid Channel::RemoveSecondarySendCodec() { 523042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _audioCodingModule.UnregisterSecondarySendCodec(); 523142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 523242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 523342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::GetSecondarySendCodec(CodecInst* codec) { 523442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.SecondarySendCodec(codec) < 0) { 523542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 523642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 523742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "GetSecondarySendCodec() Failed to get secondary sent codec from ACM"); 523842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 523942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 524042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 524142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 524242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 52438c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org// Assuming this method is called with valid payload type. 524442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetRedPayloadType(int red_payload_type) { 524542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org CodecInst codec; 524642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org bool found_red = false; 524742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 524842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org // Get default RED settings from the ACM database 524942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org const int num_codecs = AudioCodingModule::NumberOfCodecs(); 525042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org for (int idx = 0; idx < num_codecs; idx++) { 52517a7a008031d43013b01176cfe40b0fd68c0d83b5tina.legrand@webrtc.org _audioCodingModule.Codec(idx, &codec); 525242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!STR_CASE_CMP(codec.plname, "RED")) { 525342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org found_red = true; 525442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org break; 525542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 525642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 525742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 525842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!found_red) { 525942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 526042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 526142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED is not supported"); 526242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 526342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 526442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 52659d532fd2752290e85aa804f29ab9aa6c017c9208turaj@webrtc.org codec.pltype = red_payload_type; 526642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.RegisterSendCodec(codec) < 0) { 526742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 526842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 526942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in ACM module failed"); 527042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 527142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 527242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 527342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) { 527442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 527542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 527642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in RTP/RTCP module failed"); 527742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 527842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 527942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 528042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 528142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 5282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} // namespace voe 5283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} // namespace webrtc 5284