channel.cc revision 0870f02cdbcce7de8c6a4dceb6d1678c2c6c518f
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 11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "channel.h" 12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "audio_device.h" 14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "audio_frame_operations.h" 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "audio_processing.h" 16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "critical_section_wrapper.h" 1750419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org#include "logging.h" 18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "output_mixer.h" 19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "process_thread.h" 20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "rtp_dump.h" 21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "statistics.h" 22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "trace.h" 23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "transmit_mixer.h" 24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "utility.h" 25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "voe_base.h" 26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "voe_external_media.h" 27813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org#include "voe_rtp_rtcp.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 36470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendData(FrameType frameType, 38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 payloadType, 39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 timeStamp, 40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8* payloadData, 41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 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 84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InFrameType(WebRtc_Word16 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 96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_DTMF_DETECTION 97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::IncomingDtmf(const WebRtc_UWord8 digitDtmf, const bool end) 99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingDtmf(digitDtmf=%u, end=%d)", 102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com digitDtmf, end); 103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (digitDtmf != 999) 105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1069a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_telephoneEventDetectionPtr) 108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _telephoneEventDetectionPtr->OnReceivedTelephoneEventInband( 110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, digitDtmf, end); 111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnRxVadDetected(const int vadDecision) 120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnRxVadDetected(vadDecision=%d)", vadDecision); 123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1249a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); 128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendPacket(int channel, const void *data, int len) 135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket(channel=%d, len=%d)", channel, len); 141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() failed to send RTP packet due to" 146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " invalid transport object"); 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Insert extra RTP packet using if user has called the InsertExtraRTPPacket 151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // API 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_insertExtraRTPPacket) 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8* rtpHdr = (WebRtc_UWord8*)data; 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 M_PT(0); 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_extraMarkerBit) 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com M_PT = 0x80; // set the M-bit 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com M_PT += _extraPayloadType; // set the payload type 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *(++rtpHdr) = M_PT; // modify the M|PT-byte within the RTP header 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket = false; // insert one packet only 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8* bufferToSendPtr = (WebRtc_UWord8*)data; 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 bufferLength = len; 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTP packet to a file (if RTP dump is enabled). 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpDumpOut.DumpPacket((const WebRtc_UWord8*)data, len) == -1) 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP dump to output file failed"); 174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External encryption 177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encrypting) 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1799a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionRTPBufferPtr) 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for encryption buffer one time only 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTPBufferPtr = 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 188512535097e543333584f268eb62fe81c9ac76cc6xians@webrtc.org memset(_encryptionRTPBufferPtr, 0, 189512535097e543333584f268eb62fe81c9ac76cc6xians@webrtc.org kVoiceEngineMaxIpPacketSizeBytes); 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform encryption (SRTP or external) 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 encryptedBufferLength = 0; 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->encrypt(_channelId, 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTPBufferPtr, 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength, 198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&encryptedBufferLength); 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encryptedBufferLength <= 0) 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ENCRYPTION_FAILED, 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, "Channel::SendPacket() encryption failed"); 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with encrypted buffer 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr = _encryptionRTPBufferPtr; 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength = encryptedBufferLength; 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using WebRtc socket transport 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport) 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendPacket(channel, bufferToSendPtr, 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP transmission using WebRtc" 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sockets failed"); 224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using external transport transport 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2319a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendPacket(channel, 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP transmission using external" 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " transport failed"); 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendRTCPPacket(int channel, const void *data, int len) 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket(channel=%d, len=%d)", channel, len); 256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2589a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 25983661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org if (_transportPtr == NULL) 26083661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org { 26183661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 26283661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org VoEId(_instanceId,_channelId), 26383661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org "Channel::SendRTCPPacket() failed to send RTCP packet" 26483661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org " due to invalid transport object"); 26583661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org return -1; 26683661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org } 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8* bufferToSendPtr = (WebRtc_UWord8*)data; 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 bufferLength = len; 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTCP packet to a file (if RTP dump is enabled). 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpDumpOut.DumpPacket((const WebRtc_UWord8*)data, len) == -1) 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTCP dump to output file failed"); 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External encryption 281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encrypting) 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2839a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionRTCPBufferPtr) 288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for encryption buffer one time only 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTCPBufferPtr = 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform encryption (SRTP or external). 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 encryptedBufferLength = 0; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->encrypt_rtcp(_channelId, 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionRTCPBufferPtr, 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength, 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&encryptedBufferLength); 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (encryptedBufferLength <= 0) 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ENCRYPTION_FAILED, kTraceError, 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() encryption failed"); 306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with encrypted buffer 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr = _encryptionRTCPBufferPtr; 311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength = encryptedBufferLength; 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using WebRtc socket transport 316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport) 317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendRTCPPacket(channel, 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() transmission using WebRtc" 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sockets failed"); 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Packet transmission using external transport transport 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3349a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 335de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org if (_transportPtr == NULL) 336de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org { 337de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org return -1; 338de727ab260115d1813b0a039fc74fca488d0c31dhenrike@webrtc.org } 339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int n = _transportPtr->SendRTCPPacket(channel, 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferToSendPtr, 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bufferLength); 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (n < 0) 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendRTCPPacket() transmission using external" 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " transport failed"); 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return n; 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return len; 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket, 358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 rtpPacketLength, 359813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char* fromIP, 360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 fromPort) 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTPPacket(rtpPacketLength=%d," 364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " fromIP=%s, fromPort=%u)", 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPacketLength, fromIP, fromPort); 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store playout timestamp for the received RTP packet 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // to be used for upcoming delay estimations 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 playoutTimestamp(0); 370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (GetPlayoutTimeStamp(playoutTimestamp) == 0) 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playoutTimeStampRTP = playoutTimestamp; 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8* rtpBufferPtr = (WebRtc_UWord8*)incomingRtpPacket; 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 rtpBufferLength = rtpPacketLength; 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External decryption 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_decrypting) 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3819a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_decryptionRTPBufferPtr) 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for decryption buffer one time only 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decryptionRTPBufferPtr = 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform decryption (SRTP or external) 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 decryptedBufferLength = 0; 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->decrypt(_channelId, 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpBufferPtr, 396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decryptionRTPBufferPtr, 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpBufferLength, 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&decryptedBufferLength); 399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (decryptedBufferLength <= 0) 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_DECRYPTION_FAILED, kTraceError, 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTPPacket() decryption failed"); 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with decrypted buffer 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpBufferPtr = _decryptionRTPBufferPtr; 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpBufferLength = decryptedBufferLength; 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTP packet to a file (if RTP dump is enabled). 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpDumpIn.DumpPacket(rtpBufferPtr, 415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_UWord16)rtpBufferLength) == -1) 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP dump to input file failed"); 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver RTP packet to RTP/RTCP module for parsing 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The packet will be pushed back to the channel thru the 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // OnReceivedPayloadData callback so we don't push it to the ACM here 4252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtpBufferPtr, 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_UWord16)rtpBufferLength) == -1) 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTPPacket() RTP packet is invalid"); 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket, 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 rtcpPacketLength, 438813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char* fromIP, 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 fromPort) 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTCPPacket(rtcpPacketLength=%d, fromIP=%s," 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " fromPort=%u)", 444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPacketLength, fromIP, fromPort); 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Temporary buffer pointer and size for decryption 447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8* rtcpBufferPtr = (WebRtc_UWord8*)incomingRtcpPacket; 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 rtcpBufferLength = rtcpPacketLength; 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store playout timestamp for the received RTCP packet 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // which will be read by the GetRemoteRTCPData API 452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 playoutTimestamp(0); 453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (GetPlayoutTimeStamp(playoutTimestamp) == 0) 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playoutTimeStampRTCP = playoutTimestamp; 456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SRTP or External decryption 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_decrypting) 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4619a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_decryptionRTCPBufferPtr) 466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Allocate memory for decryption buffer one time only 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decryptionRTCPBufferPtr = 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes]; 470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform decryption (SRTP or external). 473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 decryptedBufferLength = 0; 474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr->decrypt_rtcp(_channelId, 475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpBufferPtr, 476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decryptionRTCPBufferPtr, 477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpBufferLength, 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int*)&decryptedBufferLength); 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (decryptedBufferLength <= 0) 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_DECRYPTION_FAILED, kTraceError, 483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTCPPacket() decryption failed"); 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Replace default data buffer with decrypted buffer 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpBufferPtr = _decryptionRTCPBufferPtr; 489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpBufferLength = decryptedBufferLength; 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTCP packet to a file (if RTP dump is enabled). 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpDumpIn.DumpPacket(rtcpBufferPtr, 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_UWord16)rtcpBufferLength) == -1) 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTCP dump to input file failed"); 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver RTCP packet to RTP/RTCP module for parsing 5032853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtcpBufferPtr, 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_UWord16)rtcpBufferLength) == -1) 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IncomingRTPPacket() RTCP packet is invalid"); 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnReceivedTelephoneEvent(const WebRtc_Word32 id, 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 event, 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool endOfEvent) 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedTelephoneEvent(id=%d, event=%u," 520fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " endOfEvent=%d)", id, event, endOfEvent); 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_DTMF_DETECTION 523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outOfBandTelephoneEventDetecion) 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5259a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_telephoneEventDetectionPtr) 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _telephoneEventDetectionPtr->OnReceivedTelephoneEventOutOfBand( 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, event, endOfEvent); 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnPlayTelephoneEvent(const WebRtc_Word32 id, 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 event, 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 lengthMs, 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 volume) 541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPlayTelephoneEvent(id=%d, event=%u, lengthMs=%u," 544fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " volume=%u)", id, event, lengthMs, volume); 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playOutbandDtmfEvent || (event > 15)) 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ignore callback since feedback is disabled or event is not a 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dtmf tone event. 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(_outputMixerPtr != NULL); 554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playing out the Dtmf tone (if playout is enabled). 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reduce length of tone with 80ms to the reduce risk of echo. 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnIncomingSSRCChanged(const WebRtc_Word32 id, 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 SSRC) 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingSSRCChanged(id=%d, SSRC=%d)", 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, SSRC); 567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset RTP-module counters since a new incoming RTP stream is detected 5722853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetReceiveDataCountersRTP(); 5732853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetStatisticsRTP(); 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserver) 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5779a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Send new SSRC to registered observer using callback 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr->OnIncomingSSRCChanged(channel, SSRC); 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid Channel::OnIncomingCSRCChanged(const WebRtc_Word32 id, 588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 CSRC, 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool added) 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingCSRCChanged(id=%d, CSRC=%d, added=%d)", 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, CSRC, added); 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserver) 599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6009a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr->OnIncomingCSRCChanged(channel, CSRC, added); 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnApplicationDataReceived(const WebRtc_Word32 id, 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 subType, 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 name, 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 length, 614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8* data) 615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnApplicationDataReceived(id=%d, subType=%u," 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " name=%u, length=%u)", 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, subType, name, length); 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserver) 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6269a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserverPtr) 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr->OnApplicationDataReceived(channel, 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com data, 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com length); 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnInitializeDecoder( 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 id, 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word8 payloadType, 643813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char payloadName[RTP_PAYLOAD_NAME_SIZE], 6440b0665acc1464d68e878f203bbc8772a0e32402dxians@google.com const int frequency, 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 channels, 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 rate) 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder(id=%d, payloadType=%d, " 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "payloadName=%s, frequency=%u, channels=%u, rate=%u)", 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, payloadType, payloadName, frequency, channels, rate); 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 653ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org assert(VoEChannelId(id) == _channelId); 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 655f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst receiveCodec = {0}; 656f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst dummyCodec = {0}; 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pltype = payloadType; 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.plfreq = frequency; 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.channels = channels; 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.rate = rate; 662f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 663f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org 6644517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org _audioCodingModule.Codec(payloadName, dummyCodec, frequency, channels); 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pacsize = dummyCodec.pacsize; 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register the new codec to the ACM 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(receiveCodec) == -1) 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 671ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org VoEId(_instanceId, _channelId), 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder() invalid codec (" 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "pt=%d, name=%s) received - 1", payloadType, payloadName); 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnPacketTimeout(const WebRtc_Word32 id) 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout(id=%d)", id); 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6879a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(_callbackCritSectPtr); 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving || _externalTransport) 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that next OnReceivedPacket() callback will trigger 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // a VE_PACKET_RECEIPT_RESTARTED callback. 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut = true; 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver callback to the observer 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout() => " 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "CallbackOnError(VE_RECEIVE_PACKET_TIMEOUT)"); 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr->CallbackOnError(channel, 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RECEIVE_PACKET_TIMEOUT); 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnReceivedPacket(const WebRtc_Word32 id, 710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const RtpRtcpPacketType packetType) 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPacket(id=%d, packetType=%d)", 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, packetType); 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 716ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org assert(VoEChannelId(id) == _channelId); 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Notify only for the case when we have restarted an RTP session. 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpPacketTimedOut && (kPacketRtp == packetType)) 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7219a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(_callbackCritSectPtr); 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset timeout mechanism 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut = false; 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver callback to the observer 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPacketTimeout() =>" 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " CallbackOnError(VE_PACKET_RECEIPT_RESTARTED)"); 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr->CallbackOnError( 734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel, 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_PACKET_RECEIPT_RESTARTED); 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnPeriodicDeadOrAlive(const WebRtc_Word32 id, 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const RTPAliveType alive) 743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPeriodicDeadOrAlive(id=%d, alive=%d)", id, alive); 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_connectionObserver) 748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 channel = VoEChannelId(id); 751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Use Alive as default to limit risk of false Dead detections 754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool isAlive(true); 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Always mark the connection as Dead when the module reports kRtpDead 757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kRtpDead == alive) 758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isAlive = false; 760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // It is possible that the connection is alive even if no RTP packet has 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // been received for a long time since the other side might use VAD/DTX 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and a low SID-packet update rate. 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((kRtpNoRtp == alive) && _playing) 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Detect Alive for all NetEQ states except for the case when we are 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in PLC_CNG state. 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // PLC_CNG <=> background noise only due to long expand or error. 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the case where the other side stops sending during CNG 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // state will be detected as Alive. Dead is is not set until after 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // missing RTCP packets for at least twelve seconds (handled 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // internally by the RTP/RTCP module). 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isAlive = (_outputSpeechType != AudioFrame::kPLCCNG); 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdateDeadOrAliveCounters(isAlive); 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Send callback to the registered observer 780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserver) 781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 7829a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserverPtr) 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr->OnPeriodicDeadOrAlive(channel, isAlive); 786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnReceivedPayloadData(const WebRtc_UWord8* payloadData, 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 payloadSize, 793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtcRTPHeader* rtpHeader) 794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData(payloadSize=%d," 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " payloadType=%u, audioChannel=%u)", 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.payloadType, 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->type.Audio.channel); 801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8020870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com _lastRemoteTimeStamp = rtpHeader->header.timestamp; 8030870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com 804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playing) 805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid inserting into NetEQ when we are not playing. Count the 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packet as discarded. 808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, 809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "received packet is discarded since playing is not" 811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " activated"); 812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets++; 813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push the incoming payload (parsed and ready for decoding) into the ACM 81716b6b90a82b796460bb20762761182c7d104cd2dtina.legrand@webrtc.org if (_audioCodingModule.IncomingPacket(payloadData, 818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *rtpHeader) != 0) 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData() unable to push data to the ACM"); 824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update the packet delay 828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdatePacketDelay(rtpHeader->header.timestamp, 829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.sequenceNumber); 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 Channel::GetAudioFrame(const WebRtc_Word32 id, 835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame& audioFrame) 836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame(id=%d)", id); 839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms raw PCM data from the ACM (mixer limits output frequency) 84163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioCodingModule.PlayoutData10Ms(audioFrame.sample_rate_hz_, 8427859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org audioFrame) == -1) 843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); 8477859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // In all likelihood, the audio in this frame is garbage. We return an 8487859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // error so that the audio mixer module doesn't add it to the mix. As 8497859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // a result, it won't be played out and the actions skipped here are 8507859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // irrelevant. 8517859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org return -1; 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_RxVadDetection) 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdateRxVadDetection(audioFrame); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Convert module ID to internal VoE channel ID 86063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.id_ = VoEChannelId(audioFrame.id_); 861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store speech type for dead-or-alive detection 86263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _outputSpeechType = audioFrame.speech_type_; 863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Perform far-end AudioProcessing module processing on the received signal 865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxApmIsEnabled) 866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ApmProcessRx(audioFrame); 868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Output volume scaling 871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputGain < 0.99f || _outputGain > 1.01f) 872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::ScaleWithSat(_outputGain, audioFrame); 874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale left and/or right channel(s) if stereo and master balance is 877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // active 878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_panLeft != 1.0f || _panRight != 1.0f) 880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 88163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.num_channels_ == 1) 882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Emulate stereo mode since panning is active. 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The mono signal is copied to both left and right channels here. 8854ecea3e1057eebf846af9b93abf8faf8571bc576andrew@webrtc.org AudioFrameOperations::MonoToStereo(&audioFrame); 886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // For true stereo mode (when we are receiving a stereo signal), no 888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // action is needed. 889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Do the panning operation (the audio frame contains stereo at this 891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stage) 892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Scale(_panLeft, _panRight, audioFrame); 893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Mix decoded PCM output with file if file mixing is enabled 896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 89863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org MixAudioWithFile(audioFrame, audioFrame.sample_rate_hz_); 899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Place channel in on-hold state (~muted) if on-hold is activated 902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputIsOnHold) 903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Mute(audioFrame); 905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // External media 908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 9109a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 91163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (audioFrame.num_channels_ == 2); 912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr->Process( 915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kPlaybackPerChannel, 91763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org (WebRtc_Word16*)audioFrame.data_, 91863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, 91963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.sample_rate_hz_, 920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Record playout if enabled 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 9269a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording && _outputFileRecorderPtr) 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 9305398d9583b713f83db843a15f8bcc2ef8df23bccniklas.enbom@webrtc.org _outputFileRecorderPtr->RecordAudioToFile(audioFrame); 931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Measure audio level (0-9) 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.ComputeLevel(audioFrame); 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::NeededFrequency(const WebRtc_Word32 id) 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::NeededFrequency(id=%d)", id); 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int highestNeeded = 0; 947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Determine highest needed receive frequency 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 receiveFrequency = _audioCodingModule.ReceiveFrequency(); 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Return the bigger of playout and receive frequency in the ACM. 952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.PlayoutFrequency() > receiveFrequency) 953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = _audioCodingModule.PlayoutFrequency(); 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = receiveFrequency; 959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Special case, if we're playing a file on the playout side 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // we take that frequency into consideration as well 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is not needed on sending side, since the codec will 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // limit the spectrum anyway. 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 9679a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr && _outputFilePlaying) 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_outputFilePlayerPtr->Frequency()>highestNeeded) 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded=_outputFilePlayerPtr->Frequency(); 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(highestNeeded); 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::CreateChannel(Channel*& channel, 982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 channelId, 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 instanceId) 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel(channelId=%d, instanceId=%d)", 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channelId, instanceId); 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = new Channel(channelId, instanceId); 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (channel == NULL) 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(instanceId,channelId), 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel() unable to allocate memory for" 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " channel"); 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::PlayNotification(const WebRtc_Word32 id, 1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 durationMs) 1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayNotification(id=%d, durationMs=%d)", 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RecordNotification(const WebRtc_Word32 id, 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 durationMs) 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordNotification(id=%d, durationMs=%d)", 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::PlayFileEnded(const WebRtc_Word32 id) 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded(id=%d)", id); 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (id == _inputFilePlayerId) 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 10319a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = false; 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => input file player module is" 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (id == _outputFilePlayerId) 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 10419a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlaying = false; 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => output file player module is" 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RecordFileEnded(const WebRtc_Word32 id) 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded(id=%d)", id); 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(id == _outputFileRecorderId); 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10599a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded() => output file recorder module is" 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Channel(const WebRtc_Word32 channelId, 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 instanceId) : 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _instanceId(instanceId), 107322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _channelId(channelId), 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule(*AudioCodingModule::Create( 107522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com VoEModuleId(instanceId, channelId))), 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 107768f2168978548bb8dd80ba77a888722bf9e5ec66perkj@webrtc.org _numSocketThreads(KNumSocketThreads), 107822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _socketTransportModule(*UdpTransport::Create( 107968f2168978548bb8dd80ba77a888722bf9e5ec66perkj@webrtc.org VoEModuleId(instanceId, channelId), _numSocketThreads)), 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_SRTP 1082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _srtpModule(*SrtpModule::CreateSrtpModule(VoEModuleId(instanceId, 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channelId))), 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpIn(*RtpDump::CreateRtpDump()), 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpOut(*RtpDump::CreateRtpDump()), 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel(), 1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport(false), 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr(NULL), 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr(NULL), 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr(NULL), 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid conflict with other channels by adding 1024 - 1026, 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // won't use as much as 1024 channels. 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying(false), 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlaying(false), 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording(false), 110022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), 110122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia(false), 110322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputExternalMedia(false), 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr(NULL), 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr(NULL), 110622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionRTPBufferPtr(NULL), 110722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decryptionRTPBufferPtr(NULL), 110822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionRTCPBufferPtr(NULL), 110922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decryptionRTCPBufferPtr(NULL), 111022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _timeStamp(0), // This is just an offset, RTP module will add it's own random offset 111122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendTelephoneEventPayloadType(106), 111222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _playoutTimeStampRTP(0), 111322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _playoutTimeStampRTCP(0), 111422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _numberOfDiscardedPackets(0), 111522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _engineStatisticsPtr(NULL), 11162919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _outputMixerPtr(NULL), 11172919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _transmitMixerPtr(NULL), 111822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _moduleProcessThreadPtr(NULL), 111922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _audioDeviceModulePtr(NULL), 112022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _voiceEngineObserverPtr(NULL), 112122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _callbackCritSectPtr(NULL), 112222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _transportPtr(NULL), 112322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encryptionPtr(NULL), 1124755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc(NULL), 112522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxAudioProcessingModulePtr(NULL), 112622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com#ifdef WEBRTC_DTMF_DETECTION 112722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _telephoneEventDetectionPtr(NULL), 112822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com#endif 112922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxVadObserverPtr(NULL), 113022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _oldVadDecision(-1), 113122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendFrameType(0), 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr(NULL), 1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr(NULL), 113422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputIsOnHold(false), 113522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _externalPlayout(false), 113622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inputIsOnHold(false), 113722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _playing(false), 113822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sending(false), 113922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _receiving(false), 114022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _mixFileWithMicrophone(false), 114122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rtpObserver(false), 114222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rtcpObserver(false), 1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute(false), 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft(1.0f), 1145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight(1.0f), 1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain(1.0f), 114722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _encrypting(false), 114822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _decrypting(false), 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent(false), 1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent(false), 1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandTelephoneEventDetection(false), 1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outOfBandTelephoneEventDetecion(false), 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraPayloadType(0), 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket(false), 1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraMarkerBit(false), 1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp(0), 11570870f02cdbcce7de8c6a4dceb6d1678c2c6c518froosa@google.com _lastRemoteTimeStamp(0), 1158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType(0), 115922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _includeAudioLevelIndication(false), 1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimedOut(false), 1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled(false), 1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds(0), 1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver(false), 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr(NULL), 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections(0), 1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections(0), 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputSpeechType(AudioFrame::kNormalSpeech), 1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _averageDelayMs(0), 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousSequenceNumber(0), 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousTimestamp(0), 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recPacketDelayMs(20), 1172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection(false), 1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled(false), 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled(false), 117522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxNsIsEnabled(false) 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Channel() - ctor"); 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.ResetDtmf(); 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.Init(); 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RtpRtcp::Configuration configuration; 11842853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.id = VoEModuleId(instanceId, channelId); 11852853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio = true; 11862853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.incoming_data = this; 11872853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.incoming_messages = this; 11882853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.outgoing_transport = this; 11892853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.rtcp_feedback = this; 11902853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio_messages = this; 11912853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 11922853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); 11932853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create far end AudioProcessing Module 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr = AudioProcessing::Create( 1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEModuleId(instanceId, channelId)); 1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::~Channel() 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::~Channel() - dtor"); 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kPlaybackPerChannel); 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMedia) 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kRecordingPerChannel); 1211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopSend(); 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopReceiving(); 1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register packet callback to ensure we're not in a callback when 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // deleting channel state, avoids race condition and deadlock. 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.InitializeReceiveSockets(NULL, 0, NULL, NULL, 0) 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register receive callback"); 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopPlayout(); 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 12289a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr) 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->StopPlayingFile(); 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr = NULL; 1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The order to safely shutdown modules in a channel is: 1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1. De-register callbacks in modules 1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 2. De-register modules in process thread 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 3. Destroy modules 1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterTransportCallback(NULL) == -1) 1257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register transport callback" 1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterVADCallback(NULL) == -1) 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register VAD callback" 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_DTMF_DETECTION 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterIncomingMessagesCallback(NULL) == -1) 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register incoming messages " 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "callback (Audio coding module)"); 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register modules in process thread 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_moduleProcessThreadPtr->DeRegisterModule(&_socketTransportModule) 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com == -1) 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to deregister socket module"); 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 12892853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()) == -1) 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to deregister RTP/RTCP module"); 1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy modules 1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::Destroy( 1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_socketTransportModule); 1300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioCodingModule::Destroy(&_audioCodingModule); 1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_SRTP 1303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SrtpModule::DestroySrtpModule(&_srtpModule); 1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr != NULL) 1306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioProcessing::Destroy(_rxAudioProcessingModulePtr); // far end APM 1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr = NULL; 1309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // End of modules shutdown 1312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete other objects 1314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpIn); 1315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpOut); 1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _encryptionRTPBufferPtr; 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _decryptionRTPBufferPtr; 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _encryptionRTCPBufferPtr; 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] _decryptionRTCPBufferPtr; 1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_callbackCritSect; 1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_fileCritSect; 1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Init() 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init()"); 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Initial sanity 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_engineStatisticsPtr == NULL) || 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_moduleProcessThreadPtr == NULL)) 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() must call SetEngineInformation() first"); 1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add modules to process thread (for periodic schedulation) 1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool processThreadFail = 13442853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ((_moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()) != 0) || 1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_moduleProcessThreadPtr->RegisterModule( 1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_socketTransportModule) != 0)); 1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else 1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com false); 1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (processThreadFail) 1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() modules not registered"); 1356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1358c450a1966965fbb3c16ec6d02c3d5cbec67df500pwestin@webrtc.org // --- ACM initialization 1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.InitializeReceiver() == -1) || 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_AVT 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // out-of-band Dtmf tones are played out by default 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.SetDtmfPlayoutStatus(true) == -1) || 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.InitializeSender() == -1)) 1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to initialize the ACM - 1"); 1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- RTP/RTCP module initialization 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that RTCP is enabled by default for the created channel. 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the module will keep generating RTCP until it is explicitly 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // disabled by the user. 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // After StopListen (when no sockets exists), RTCP packets will no longer 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // be transmitted since the Transport object will then be invalid. 1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool rtpRtcpFail = 13822853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ((_rtpRtcpModule->SetTelephoneEventStatus(false, true, true) == -1) || 1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTCP is enabled by default 13842853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->SetRTCPStatus(kRtcpCompound) == -1)); 1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpRtcpFail) 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() RTP/RTCP module not initialized"); 1390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all permanent callbacks 1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool fail = 1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterTransportCallback(this) == -1) || 1396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterVADCallback(this) == -1); 1397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fail) 1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() callbacks not registered"); 1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all supported codecs to the receiving side of the 1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTP/RTCP module 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.Codec(idx, codec) == -1) || 14162853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to register %s (%d/%d/%d/%d) " 1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "to RTP/RTCP receiver", 1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() %s (%d/%d/%d/%d) has been added to " 1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP receiver", 1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that PCMU is used as default codec on the sending side 14364517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) 1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SetSendCodec(codec); 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register default PT for outband 'telephone-event' 1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "telephone-event")) 1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 14442853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterReceiveCodec(codec) == -1)) 1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register outband " 1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "'telephone-event' (%d/%d) correctly", 1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "CN")) 1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.RegisterSendCodec(codec) == -1) || 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_audioCodingModule.RegisterReceiveCodec(codec) == -1) || 14592853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) 1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register CN (%d/%d) " 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly - 1", 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_RED 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register RED to the receiving side of the ACM. 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will not receive an OnInitializeDecoder() callback for RED. 1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "RED")) 1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) == -1) 1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register RED (%d/%d) " 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly", 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that the WebRtcSocketTransport implementation is used as 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Transport on the sending side 148783661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org { 148883661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org // A lock is needed here since users can call 148983661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org // RegisterExternalTransport() at the same time. 14909a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 149183661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org _transportPtr = &_socketTransportModule; 149283661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org } 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize the far end AP module 1496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Using 8 kHz as initial Fs, the same as in transmission. Might be 1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // changed at the first receiving audio. 1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr == NULL) 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NO_MEMORY, kTraceCritical, 1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to create the far-end AudioProcessing" 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " module"); 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->set_sample_rate_hz(8000)) 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to set the sample rate to 8K for" 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " far-end AP module"); 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->set_num_channels(1, 1) != 0) 1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOUNDCARD_ERROR, kTraceWarning, 1519755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Init() failed to set channels for the primary audio stream"); 1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->high_pass_filter()->Enable( 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_HP_DEFAULT_STATE) != 0) 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to set the high-pass filter for" 1528fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " far-end AP module"); 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->set_level( 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE) != 0) 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set noise reduction level for far-end" 1537fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " AP module"); 1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->Enable( 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_STATE) != 0) 1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set noise reduction state for far-end" 1545fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " AP module"); 1546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_mode( 1549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (GainControl::Mode)WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_MODE) != 0) 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set AGC mode for far-end AP module"); 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->Enable( 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_AGC_DEFAULT_STATE) != 0) 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceWarning, 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Init() failed to set AGC state for far-end AP module"); 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetEngineInformation(Statistics& engineStatistics, 1568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OutputMixer& outputMixer, 1569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com voe::TransmitMixer& transmitMixer, 1570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessThread& moduleProcessThread, 1571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioDeviceModule& audioDeviceModule, 1572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoiceEngineObserver* voiceEngineObserver, 1573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionWrapper* callbackCritSect) 1574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetEngineInformation()"); 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr = &engineStatistics; 1578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr = &outputMixer; 1579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transmitMixerPtr = &transmitMixer, 1580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _moduleProcessThreadPtr = &moduleProcessThread; 1581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioDeviceModulePtr = &audioDeviceModule; 1582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = voiceEngineObserver; 1583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSectPtr = callbackCritSect; 1584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateLocalTimeStamp() 1589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 159163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 1592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartPlayout() 1597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayout()"); 1600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playing) 1601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add participant as candidates for mixing. 1605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) 1606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayout() failed to add participant to mixer"); 1610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playing = true; 1614ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1615ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1616ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 1617ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopPlayout() 1623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayout()"); 1626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playing) 1627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Remove participant as candidates for mixing 1631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) 1632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayout() failed to remove participant from mixer"); 1636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playing = false; 1640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 1641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartSend() 1647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartSend()"); 1650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1651e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // A lock is needed because |_sending| can be accessed or modified by 1652e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // another thread at the same time. 16539a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1654e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1655e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org if (_sending) 1656e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org { 1657e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org return 0; 1658e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org } 1659e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = true; 1660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1661e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 16622853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(true) != 0) 1663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to start sending"); 16679a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1668e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = false; 1669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1671e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopSend() 1677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopSend()"); 1680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1681e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // A lock is needed because |_sending| can be accessed or modified by 1682e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org // another thread at the same time. 16839a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1684e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1685e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org if (!_sending) 1686e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org { 1687e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org return 0; 1688e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org } 1689e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org _sending = false; 1690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1691e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset sending SSRC and sequence number and triggers direct transmission 1693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // of RTCP BYE 16942853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(false) == -1 || 16952853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetSendDataCountersRTP() == -1) 1696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to stop sending"); 1700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartReceiving() 1707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartReceiving()"); 1710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving) 1711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // If external transport is used, we will only initialize/set the variables 1715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // after this section, since we are not using the WebRtc transport but 1716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // still need to keep track of e.g. if we are receiving. 1717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport) 1719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_socketTransportModule.ReceiveSocketsInitialized()) 1721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKETS_NOT_INITED, kTraceError, 1724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartReceive() must set local receiver first"); 1725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.StartReceiving(KNumberOfSocketBuffers) != 0) 1728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 1731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartReceiving() failed to start receiving"); 1732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _receiving = true; 1737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets = 0; 1738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopReceiving() 1743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopReceiving()"); 1746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_receiving) 1747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_externalTransport && 1753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.ReceiveSocketsInitialized()) 1754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.StopReceiving() != 0) 1756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 1759af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org "StopReceiving() failed to stop receiving."); 1760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 17642853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org bool dtmfDetection = _rtpRtcpModule->TelephoneEvent(); 1765af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org // Recover DTMF detection status. 17662853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org WebRtc_Word32 ret = _rtpRtcpModule->SetTelephoneEventStatus(dtmfDetection, 17672853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org true, true); 1768af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org if (ret != 0) { 1769af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org _engineStatisticsPtr->SetLastError( 1770af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org VE_INVALID_OPERATION, kTraceWarning, 1771af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org "StopReceiving() failed to restore telephone-event status."); 1772af71f0e5d98d894b22969d4714821b54218bc083henrika@webrtc.org } 1773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RegisterReceiveCodecsToRTPModule(); 1774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _receiving = false; 1775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetLocalReceiver(const WebRtc_UWord16 rtpPort, 1781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 rtcpPort, 1782813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char ipAddr[64], 1783813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char multicastIpAddr[64]) 1784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetLocalReceiver()"); 1787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 1789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() conflict with external transport"); 1793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 1797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_SENDING, kTraceError, 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() already sending"); 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving) 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_LISTENING, kTraceError, 1807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() already receiving"); 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.InitializeReceiveSockets(this, 1812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort, 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ipAddr, 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com multicastIpAddr, 1815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPort) != 0) 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 1818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 1819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 1820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kIpAddressInvalid: 1822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_IP_ADDRESS, kTraceError, 1824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() invalid IP address"); 1825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kSocketInvalid: 1827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 1829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() invalid socket"); 1830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kPortInvalid: 1832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_PORT_NMBR, kTraceError, 1834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() invalid port"); 1835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kFailedToBindPort: 1837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BINDING_SOCKET_TO_LOCAL_ADDRESS_FAILED, kTraceError, 1839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() binding failed"); 1840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 1844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() undefined socket error"); 1845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetLocalReceiver(int& port, int& RTCPport, char ipAddr[64]) 1856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetLocalReceiver()"); 1859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 1861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalReceiver() conflict with external transport"); 1865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1868813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 1869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtpPort(0); 1870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpPort(0); 1871813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char multicastIpAddr[UdpTransport::kIpAddressVersion6Length] = {0}; 1872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Acquire socket information from the socket module 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.ReceiveSocketInformation(ipAddrTmp, 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort, 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPort, 1877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com multicastIpAddr) != 0) 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_GET_SOCKET_INFO, kTraceError, 1881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalReceiver() unable to retrieve socket information"); 1882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver valid results to the user 1886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com port = static_cast<int> (rtpPort); 1887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPport = static_cast<int> (rtcpPort); 1888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (ipAddr != NULL) 1889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(ipAddr, ipAddrTmp); 1891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 1897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 1898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendDestination(const WebRtc_UWord16 rtpPort, 1899813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char ipAddr[64], 1900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int sourcePort, 1901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 rtcpPort) 1902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendDestination()"); 1905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 1907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 1910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() conflict with external transport"); 1911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize ports and IP address for the remote (destination) side. 1915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // By default, the sockets used for receiving are used for transmission as 1916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // well, hence the source ports for outgoing packets are the same as the 1917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // receiving ports specified in SetLocalReceiver. 1918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // If an extra send socket has been created, it will be utilized until a 1919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // new source port is specified or until the channel has been deleted and 1920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // recreated. If no socket exists, sockets will be created when the first 1921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTP and RTCP packets shall be transmitted (see e.g. 1922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // UdpTransportImpl::SendPacket()). 1923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // NOTE: this function does not require that sockets exists; all it does is 1925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // to build send structures to be used with the sockets when they exist. 1926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // It is therefore possible to call this method before SetLocalReceiver. 1927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // However, sockets must exist if a multi-cast address is given as input. 1928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Build send structures and enable QoS (if enabled and supported) 1930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.InitializeSendSockets( 1931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ipAddr, rtpPort, rtcpPort) != UdpTransport::kNoSocketError) 1932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 1934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 1935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 1936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kIpAddressInvalid: 1938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_IP_ADDRESS, kTraceError, 1940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() invalid IP address 1"); 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kSocketInvalid: 1943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 1945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() invalid socket 1"); 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kQosError: 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_GQOS_ERROR, kTraceError, 1950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() failed to set QoS"); 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kMulticastAddressInvalid: 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_MULTICAST_ADDRESS, kTraceError, 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() invalid multicast address"); 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 1958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() undefined socket error 1"); 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Check if the user has specified a non-default source port different from 1967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // the local receive port. 1968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // If so, an extra local socket will be created unless the source port is 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // not unique. 1970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sourcePort != kVoEDefault) 1971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 receiverRtpPort(0); 1973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpNA(0); 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.ReceiveSocketInformation(NULL, 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiverRtpPort, 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpNA, 1977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NULL) != 0) 1978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_GET_SOCKET_INFO, kTraceError, 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() failed to retrieve socket information"); 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 sourcePortUW16 = 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static_cast<WebRtc_UWord16> (sourcePort); 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // An extra socket will only be created if the specified source port 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // differs from the local receive port. 1990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sourcePortUW16 != receiverRtpPort) 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize extra local socket to get a different source port 1993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // than the local 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // receiver port. Always use default source for RTCP. 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, this calls UdpTransport::CloseSendSockets(). 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.InitializeSourcePorts( 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sourcePortUW16, 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sourcePortUW16+1) != 0) 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kIpAddressInvalid: 2005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_IP_ADDRESS, kTraceError, 2007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() invalid IP address 2"); 2008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kSocketInvalid: 2010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 2012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() invalid socket 2"); 2013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 2017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() undefined socket error 2"); 2018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() extra local socket is created" 2025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " to facilitate unique source port"); 2026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 2030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendDestination() sourcePort equals the local" 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " receive port => no extra socket is created"); 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 2039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 2041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendDestination(int& port, 2043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com char ipAddr[64], 2044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int& sourcePort, 2045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int& RTCPport) 2046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendDestination()"); 2049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 2051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 2054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendDestination() conflict with external transport"); 2055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2058813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 2059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtpPort(0); 2060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpPort(0); 2061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtpSourcePort(0); 2062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpSourcePort(0); 2063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Acquire sending socket information from the socket module 2065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.SendSocketInformation(ipAddrTmp, rtpPort, rtcpPort); 2066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.SourcePorts(rtpSourcePort, rtcpSourcePort); 2067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Deliver valid results to the user 2069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com port = static_cast<int> (rtpPort); 2070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPport = static_cast<int> (rtcpPort); 2071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com sourcePort = static_cast<int> (rtpSourcePort); 2072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (ipAddr != NULL) 2073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(ipAddr, ipAddrTmp); 2075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 2080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetNetEQPlayoutMode(NetEqModes mode) 2084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetNetEQPlayoutMode()"); 2087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioPlayoutMode playoutMode(voice); 2088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqDefault: 2091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = voice; 2092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqStreaming: 2094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = streaming; 2095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNetEqFax: 2097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutMode = fax; 2098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetPlayoutMode(playoutMode) != 0) 2101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetNetEQPlayoutMode() failed to set playout mode"); 2105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetEQPlayoutMode(NetEqModes& mode) 2112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const AudioPlayoutMode playoutMode = _audioCodingModule.PlayoutMode(); 2114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (playoutMode) 2115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case voice: 2117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqDefault; 2118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case streaming: 2120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqStreaming; 2121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case fax: 2123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNetEqFax; 2124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetEQPlayoutMode() => mode=%u", mode); 2129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetNetEQBGNMode(NetEqBgnModes mode) 2134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetNetEQPlayoutMode()"); 2137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ACMBackgroundNoiseMode noiseMode(On); 2138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kBgnOn: 2141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com noiseMode = On; 2142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kBgnFade: 2144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com noiseMode = Fade; 2145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kBgnOff: 2147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com noiseMode = Off; 2148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetBackgroundNoiseMode(noiseMode) != 0) 2151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetBackgroundNoiseMode() failed to set noise mode"); 2155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOnHoldStatus(bool enable, OnHoldModes mode) 2162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOnHoldStatus()"); 2165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (mode == kHoldSendAndPlay) 2166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputIsOnHold = enable; 2168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputIsOnHold = enable; 2169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (mode == kHoldPlayOnly) 2171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputIsOnHold = enable; 2173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (mode == kHoldSendOnly) 2175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputIsOnHold = enable; 2177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOnHoldStatus(bool& enabled, OnHoldModes& mode) 2183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetOnHoldStatus()"); 2186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (_outputIsOnHold || _inputIsOnHold); 2187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputIsOnHold && _inputIsOnHold) 2188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldSendAndPlay; 2190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (_outputIsOnHold && !_inputIsOnHold) 2192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldPlayOnly; 2194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (!_outputIsOnHold && _inputIsOnHold) 2196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kHoldSendOnly; 2198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetOnHoldStatus() => enabled=%d, mode=%d", 2201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, mode); 2202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 2207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterVoiceEngineObserver()"); 22109a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 2213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterVoiceEngineObserver() observer already enabled"); 2217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = &observer; 2220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterVoiceEngineObserver() 2225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterVoiceEngineObserver()"); 22289a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_voiceEngineObserverPtr) 2231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterVoiceEngineObserver() observer already disabled"); 2235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = NULL; 2238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetEQBGNMode(NetEqBgnModes& mode) 2243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ACMBackgroundNoiseMode noiseMode(On); 2245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.BackgroundNoiseMode(noiseMode); 2246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (noiseMode) 2247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case On: 2249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kBgnOn; 2250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case Fade: 2252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kBgnFade; 2253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case Off: 2255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kBgnOff; 2256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetEQBGNMode() => mode=%u", mode); 2260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendCodec(CodecInst& codec) 2265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (_audioCodingModule.SendCodec(codec)); 2267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecCodec(CodecInst& codec) 2271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (_audioCodingModule.ReceiveCodec(codec)); 2273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCodec(const CodecInst& codec) 2277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCodec()"); 2280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterSendCodec(codec) != 0) 2282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to ACM"); 2285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22882853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 22902853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 22912853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 2294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to" 2296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " RTP/RTCP module"); 2297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23012853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) 2302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to set audio packet size"); 2305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) 2313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetVADStatus(mode=%d)", mode); 2316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // To disable VAD, DTX must be disabled too 2317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disableDTX = ((enableVAD == false) ? true : disableDTX); 2318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetVAD(!disableDTX, enableVAD, mode) != 0) 2319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetVADStatus() failed to set VAD"); 2323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) 2330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetVADStatus"); 2333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.VAD(disabledDTX, enabledVAD, mode) != 0) 2334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetVADStatus() failed to get VAD status"); 2338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disabledDTX = !disabledDTX; 2341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRecPayloadType(const CodecInst& codec) 2346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRecPayloadType()"); 2349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playing) 2351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 2354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while playing"); 2355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_receiving) 2358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_LISTENING, kTraceError, 2361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while listening"); 2362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codec.pltype == -1) 2366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register the selected codec (RTP/RTCP module and ACM) 2368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word8 pltype(-1); 2370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst rxCodec = codec; 2371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get payload type for the given codec 23732853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ReceivePayloadType(rxCodec, &pltype); 2374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rxCodec.pltype = pltype; 2375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23762853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DeRegisterReceivePayload(pltype) != 0) 2377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 2380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module deregistration " 2382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 2383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.UnregisterReceiveCodec(rxCodec.pltype) != 0) 2386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM deregistration failed - 1"); 2390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23952853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 2396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // First attempt to register failed => de-register and try again 23982853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterReceivePayload(codec.pltype); 23992853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0) 2400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module registration failed"); 2404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 2408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.UnregisterReceiveCodec(codec.pltype); 2410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterReceiveCodec(codec) != 0) 2411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM registration failed - 1"); 2415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecPayloadType(CodecInst& codec) 2423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType()"); 2426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word8 payloadType(-1); 24272853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->ReceivePayloadType(codec, &payloadType) != 0) 2428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 243037198007eab6731fa0f77866155dd4f2b332a262henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 2431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRecPayloadType() failed to retrieve RX payload type"); 2432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = payloadType; 2435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType() => pltype=%u", codec.pltype); 2437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMREncFormat(AmrMode mode) 2442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMREncFormat()"); 2445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 2447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRDecFormat(AmrMode mode) 2452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRDecFormat()"); 2455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 2457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRWbEncFormat(AmrMode mode) 2462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRWbEncFormat()"); 2465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 2467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetAMRWbDecFormat(AmrMode mode) 2473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetAMRWbDecFormat()"); 2476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ACM doesn't support AMR 2478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) 2483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCNPayloadType()"); 2486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 2488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 samplingFreqHz(-1); 24894517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org const int kMono = 1; 2490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (frequency == kFreq32000Hz) 2491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 32000; 2492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (frequency == kFreq16000Hz) 2493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 16000; 2494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 24954517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org if (_audioCodingModule.Codec("CN", codec, samplingFreqHz, kMono) == -1) 2496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to retrieve default CN codec " 2500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "settings"); 2501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Modify the payload type (must be set to dynamic range) 2505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = type; 2506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterSendCodec(codec) != 0) 2508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to ACM"); 2512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25152853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 25172853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 25182853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to RTP/RTCP " 2523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 2524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACInitTargetRate(int rateBps, bool useFixedFrameSize) 2532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACInitTargetRate()"); 2535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 2537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SendCodec(sendCodec) == -1) 2538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() failed to retrieve send codec"); 2542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This API is only valid if iSAC is setup to run in channel-adaptive 2547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // mode. 2548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We do not validate the adaptive mode here. It is done later in the 2549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // ConfigISACBandwidthEstimator() API. 2550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() send codec is not iSAC"); 2553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 initFrameSizeMsec(0); 2557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 2558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that 0 is a valid and corresponds to "use default 2560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps != 0 && 2561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rateBps < kVoiceEngineMinIsacInitTargetRateBpsWb) || 2562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsWb)) 2563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() invalid target rate - 1"); 2567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 30 or 60ms 2570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com initFrameSizeMsec = (WebRtc_UWord8)(sendCodec.pacsize / 16); 2571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 2573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps != 0 && 2575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rateBps < kVoiceEngineMinIsacInitTargetRateBpsSwb) || 2576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacInitTargetRateBpsSwb)) 2577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() invalid target rate - 2"); 2581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com initFrameSizeMsec = (WebRtc_UWord8)(sendCodec.pacsize / 32); // 30ms 2584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.ConfigISACBandwidthEstimator( 2587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com initFrameSizeMsec, rateBps, useFixedFrameSize) == -1) 2588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACInitTargetRate() iSAC BWE config failed"); 2592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACMaxRate(int rateBps) 2600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACMaxRate()"); 2603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 2605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SendCodec(sendCodec) == -1) 2606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() failed to retrieve send codec"); 2610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This API is only valid if iSAC is selected as sending codec. 2615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() send codec is not iSAC"); 2618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 2621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps < kVoiceEngineMinIsacMaxRateBpsWb) || 2623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacMaxRateBpsWb)) 2624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() invalid max rate - 1"); 2628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 2632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((rateBps < kVoiceEngineMinIsacMaxRateBpsSwb) || 2634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (rateBps > kVoiceEngineMaxIsacMaxRateBpsSwb)) 2635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() invalid max rate - 2"); 2639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 2643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 2646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() unable to set max rate while sending"); 2647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set the maximum instantaneous rate of iSAC (works for both adaptive 2651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and non-adaptive mode) 2652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetISACMaxRate(rateBps) == -1) 2653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxRate() failed to set max rate"); 2657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetISACMaxPayloadSize(int sizeBytes) 2665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetISACMaxPayloadSize()"); 2668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst sendCodec; 2669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SendCodec(sendCodec) == -1) 2670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() failed to retrieve send codec"); 2674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (STR_CASE_CMP(sendCodec.plname, "ISAC") != 0) 2677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CODEC_ERROR, kTraceError, 2680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() send codec is not iSAC"); 2681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (16000 == sendCodec.plfreq) 2684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesWb) || 2686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesWb)) 2687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() invalid max payload - 1"); 2691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (32000 == sendCodec.plfreq) 2695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((sizeBytes < kVoiceEngineMinIsacMaxPayloadSizeBytesSwb) || 2697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (sizeBytes > kVoiceEngineMaxIsacMaxPayloadSizeBytesSwb)) 2698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() invalid max payload - 2"); 2702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 2706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 2709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() unable to set max rate while sending"); 2710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetISACMaxPayloadSize(sizeBytes) == -1) 2714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 2717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetISACMaxPayloadSize() failed to set max payload size"); 2718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 Channel::RegisterExternalTransport(Transport& transport) 2724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalTransport()"); 2727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27289a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 2731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Sanity checks for default (non external transport) to avoid conflict with 2732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // WebRtc sockets. 2733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SendSocketsInitialized()) 2734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_SEND_SOCKETS_CONFLICT, 2736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() send sockets already initialized"); 2738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.ReceiveSocketsInitialized()) 2741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_RECEIVE_SOCKETS_CONFLICT, 2743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() receive sockets already initialized"); 2745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 2748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 2749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, 2751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 2752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() external transport already enabled"); 2753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = true; 2756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = &transport; 2757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalTransport() 2762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalTransport()"); 2765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27669a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 276783661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org 2768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_transportPtr) 2769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() external transport already " 2773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "disabled"); 2774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = false; 2777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_EXTERNAL_TRANSPORT 2778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = NULL; 2779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() all transport is disabled"); 2781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else 2782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = &_socketTransportModule; 2783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() internal Transport is enabled"); 2785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 2786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ReceivedRTPPacket(const WebRtc_Word8* data, WebRtc_Word32 length) 2791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ReceivedRTPPacket()"); 2794813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char dummyIP[] = "127.0.0.1"; 2795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com IncomingRTPPacket(data, length, dummyIP, 0); 2796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ReceivedRTCPPacket(const WebRtc_Word8* data, WebRtc_Word32 length) 2801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ReceivedRTCPPacket()"); 2804813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char dummyIP[] = "127.0.0.1"; 2805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com IncomingRTCPPacket(data, length, dummyIP, 0); 2806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifndef WEBRTC_EXTERNAL_TRANSPORT 2810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSourceInfo(int& rtpPort, int& rtcpPort, char ipAddr[64]) 2812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSourceInfo()"); 2815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtpPortModule; 2817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpPortModule; 2818813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char ipaddr[UdpTransport::kIpAddressVersion6Length] = {0}; 2819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.RemoteSocketInformation(ipaddr, 2821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPortModule, 2822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPortModule) != 0) 2823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 2826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSourceInfo() failed to retrieve remote socket information"); 2827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(ipAddr, ipaddr); 2830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort = rtpPortModule; 2831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPort = rtcpPortModule; 2832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSourceInfo() => rtpPort=%d, rtcpPort=%d, ipAddr=%s", 2835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort, rtcpPort, ipAddr); 2836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EnableIPv6() 2841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EnableIPv6()"); 2844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.ReceiveSocketsInitialized() || 2845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.SendSocketsInitialized()) 2846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableIPv6() socket layer is already initialized"); 2850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.EnableIpV6() != 0) 2853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 2856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableIPv6() failed to enable IPv6"); 2857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const UdpTransport::ErrorCode lastError = 2858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError(); 2859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport::LastError() => %d", lastError); 2861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 2867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::IPv6IsEnabled() const 2868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool isEnabled = _socketTransportModule.IpV6Enabled(); 2870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "IPv6IsEnabled() => %d", isEnabled); 2872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return isEnabled; 2873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSourceFilter(int rtpPort, int rtcpPort, const char ipAddr[64]) 2877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSourceFilter()"); 2880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SetFilterPorts( 2881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static_cast<WebRtc_UWord16>(rtpPort), 2882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static_cast<WebRtc_UWord16>(rtcpPort)) != 0) 2883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 2886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSourceFilter() failed to set filter ports"); 2887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const UdpTransport::ErrorCode lastError = 2888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError(); 2889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport::LastError() => %d", 2891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lastError); 2892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2894813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char* filterIpAddress = ipAddr; 2895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SetFilterIP(filterIpAddress) != 0) 2896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_IP_ADDRESS, kTraceError, 2899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSourceFilter() failed to set filter IP address"); 2900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const UdpTransport::ErrorCode lastError = 2901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError(); 2902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport::LastError() => %d", lastError); 2904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSourceFilter(int& rtpPort, int& rtcpPort, char ipAddr[64]) 2911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSourceFilter()"); 2914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtpFilterPort(0); 2915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 rtcpFilterPort(0); 2916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.FilterPorts(rtpFilterPort, rtcpFilterPort) != 0) 2917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 2920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSourceFilter() failed to retrieve filter ports"); 2921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2922813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0}; 2923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.FilterIP(ipAddrTmp) != 0) 2924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // no filter has been configured (not seen as an error) 2926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memset(ipAddrTmp, 2927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 0, UdpTransport::kIpAddressVersion6Length); 2928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort = static_cast<int> (rtpFilterPort); 2930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtcpPort = static_cast<int> (rtcpFilterPort); 2931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(ipAddr, ipAddrTmp); 2932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSourceFilter() => rtpPort=%d, rtcpPort=%d, ipAddr=%s", 2934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpPort, rtcpPort, ipAddr); 2935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 2939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendTOS(int DSCP, int priority, bool useSetSockopt) 2940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendTOS(DSCP=%d, useSetSockopt=%d)", 2943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DSCP, (int)useSetSockopt); 2944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set TOS value and possibly try to force usage of setsockopt() 2946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SetToS(DSCP, useSetSockopt) != 0) 2947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 2949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 2950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 2951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kTosError: 2953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() TOS error"); 2955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kQosError: 2957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_TOS_GQOS_CONFLICT, kTraceError, 2959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() GQOS error"); 2960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kTosInvalid: 2962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // can't switch SetSockOpt method without disabling TOS first, or 2963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // SetSockopt() call failed 2964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_TOS_INVALID, kTraceError, 2965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() invalid TOS"); 2966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kSocketInvalid: 2968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError, 2969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() invalid Socket"); 2970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() TOS error"); 2974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 2977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport => lastError = %d", 2978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lastSockError); 2979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Set priority (PCP) value, -1 means don't change 2983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (-1 != priority) 2984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SetPCP(priority) != 0) 2986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 2988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 2989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 2990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kPcpError: 2992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 2993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() PCP error"); 2994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kQosError: 2996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_TOS_GQOS_CONFLICT, kTraceError, 2998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() GQOS conflict"); 2999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kSocketInvalid: 3001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_ERROR, kTraceError, 3003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() invalid Socket"); 3004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 3006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError, 3007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTOS() PCP error"); 3008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 3011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 3012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport => lastError = %d", 3013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lastSockError); 3014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendTOS(int &DSCP, int& priority, bool &useSetSockopt) 3023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendTOS(DSCP=?, useSetSockopt=?)"); 3026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 dscp(0), prio(0); 3027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool setSockopt(false); 3028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.ToS(dscp, setSockopt) != 0) 3029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTOS() failed to get TOS info"); 3033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.PCP(prio) != 0) 3036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTOS() failed to get PCP info"); 3040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DSCP = static_cast<int> (dscp); 3043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com priority = static_cast<int> (prio); 3044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com useSetSockopt = setSockopt; 3045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTOS() => DSCP=%d, priority=%d, useSetSockopt=%d", 3047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DSCP, priority, (int)useSetSockopt); 3048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#if defined(_WIN32) 3052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendGQoS(bool enable, int serviceType, int overrideDSCP) 3054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendGQoS(enable=%d, serviceType=%d, " 3057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "overrideDSCP=%d)", 3058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, serviceType, overrideDSCP); 3059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(!_socketTransportModule.ReceiveSocketsInitialized()) 3060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKETS_NOT_INITED, kTraceError, 3063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() GQoS state must be set after sockets are created"); 3064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(!_socketTransportModule.SendSocketsInitialized()) 3067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_DESTINATION_NOT_INITED, kTraceError, 3070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() GQoS state must be set after sending side is " 3071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "initialized"); 3072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable && 3075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (serviceType != SERVICETYPE_BESTEFFORT) && 3076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (serviceType != SERVICETYPE_CONTROLLEDLOAD) && 3077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (serviceType != SERVICETYPE_GUARANTEED) && 3078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (serviceType != SERVICETYPE_QUALITATIVE)) 3079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() Invalid service type"); 3083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable && ((overrideDSCP < 0) || (overrideDSCP > 63))) 3086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() Invalid overrideDSCP value"); 3090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid GQoS/ToS conflict when user wants to override the default DSCP 3094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // mapping 3095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool QoS(false); 3096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 sType(0); 3097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 ovrDSCP(0); 3098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.QoS(QoS, sType, ovrDSCP)) 3099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError, 3102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() failed to get QOS info"); 3103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (QoS && ovrDSCP == 0 && overrideDSCP != 0) 3106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_TOS_GQOS_CONFLICT, kTraceError, 3109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() QOS is already enabled and overrideDSCP differs," 3110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " not allowed"); 3111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 maxBitrate(0); 3114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_socketTransportModule.SetQoS(enable, 3115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static_cast<WebRtc_Word32>(serviceType), 3116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxBitrate, 3117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com static_cast<WebRtc_Word32>(overrideDSCP), 3118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com true)) 3119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UdpTransport::ErrorCode lastSockError( 3121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.LastError()); 3122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (lastSockError) 3123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case UdpTransport::kQosError: 3125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_GQOS_ERROR, kTraceError, 3126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() QOS error"); 3127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 3129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError, 3130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendGQoS() Socket error"); 3131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 3132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 3134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "UdpTransport() => lastError = %d", 3135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com lastSockError); 3136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 3141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#if defined(_WIN32) 3143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendGQoS(bool &enabled, int &serviceType, int &overrideDSCP) 3145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendGQoS(enable=?, serviceType=?, " 3148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "overrideDSCP=?)"); 3149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool QoS(false); 3151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 serviceTypeModule(0); 3152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 overrideDSCPModule(0); 3153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _socketTransportModule.QoS(QoS, serviceTypeModule, overrideDSCPModule); 3154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = QoS; 3156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com serviceType = static_cast<int> (serviceTypeModule); 3157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com overrideDSCP = static_cast<int> (overrideDSCPModule); 3158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendGQoS() => enabled=%d, serviceType=%d, overrideDSCP=%d", 3161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enabled, serviceType, overrideDSCP); 3162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 3165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 3166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetPacketTimeoutNotification(bool enable, int timeoutSeconds) 3169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetPacketTimeoutNotification()"); 3172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable) 3173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 RTPtimeoutMS = 1000*timeoutSeconds; 3175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 RTCPtimeoutMS = 0; 31762853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPacketTimeout(RTPtimeoutMS, RTCPtimeoutMS); 3177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled = true; 3178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds = timeoutSeconds; 3179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 31822853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPacketTimeout(0, 0); 3183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpPacketTimeOutIsEnabled = false; 3184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpTimeOutSeconds = 0; 3185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPacketTimeoutNotification(bool& enabled, int& timeoutSeconds) 3191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPacketTimeoutNotification()"); 3194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = _rtpPacketTimeOutIsEnabled; 3195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 3196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeoutSeconds = _rtpTimeOutSeconds; 3198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPacketTimeoutNotification() => enabled=%d," 3201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " timeoutSeconds=%d", 3202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, timeoutSeconds); 3203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterDeadOrAliveObserver(VoEConnectionObserver& observer) 3208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterDeadOrAliveObserver()"); 32119a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_connectionObserverPtr) 3214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, kTraceError, 3216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterDeadOrAliveObserver() observer already enabled"); 3217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr = &observer; 3221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver = true; 3222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterDeadOrAliveObserver() 3228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterDeadOrAliveObserver()"); 32319a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_connectionObserverPtr) 3234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterDeadOrAliveObserver() observer already disabled"); 3238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserver = false; 3242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _connectionObserverPtr = NULL; 3243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetPeriodicDeadOrAliveStatus(bool enable, int sampleTimeSeconds) 3249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetPeriodicDeadOrAliveStatus()"); 3252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_connectionObserverPtr) 3253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetPeriodicDeadOrAliveStatus() connection observer has" 3256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " not been registered"); 3257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enable) 3259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ResetDeadOrAliveCounters(); 3261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enabled(false); 3263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 currentSampleTimeSec(0); 3264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store last state (will be used later if dead-or-alive is disabled). 32652853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, currentSampleTimeSec); 3266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update the dead-or-alive state. 32672853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetPeriodicDeadOrAliveStatus( 3268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enable, (WebRtc_UWord8)sampleTimeSeconds) != 0) 3269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 3272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 3273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetPeriodicDeadOrAliveStatus() failed to set dead-or-alive " 3274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "status"); 3275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!enable) 3278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Restore last utilized sample time. 3280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Without this, the sample time would always be reset to default 3281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (2 sec), each time dead-or-alived was disabled without sample-time 3282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // parameter. 32832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetPeriodicDeadOrAliveStatus(enable, 3284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com currentSampleTimeSec); 3285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds) 3291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 32922853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus( 3293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, 3294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (WebRtc_UWord8&)sampleTimeSeconds); 3295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1), 3296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPeriodicDeadOrAliveStatus() => enabled=%d," 3297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " sampleTimeSeconds=%d", 3298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, sampleTimeSeconds); 3299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 3303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendUDPPacket(const void* data, 3304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int length, 3305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int& transmittedBytes, 3306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool useRtcpSocket) 3307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendUDPPacket()"); 3310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 3311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError, 3314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() external transport is enabled"); 3315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 33172853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (useRtcpSocket && !_rtpRtcpModule->RTCP()) 3318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTCP_ERROR, kTraceError, 3321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() RTCP is disabled"); 3322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_sending) 3325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 3328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() not sending"); 3329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com char* dataC = new char[length]; 3333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL == dataC) 3334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NO_MEMORY, kTraceError, 3337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() memory allocation failed"); 3338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memcpy(dataC, data, length); 3341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transmittedBytes = SendPacketRaw(dataC, length, useRtcpSocket); 3343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete [] dataC; 3345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataC = NULL; 3346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (transmittedBytes <= 0) 3348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_ERROR, kTraceError, 3351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() transmission failed"); 3352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com transmittedBytes = 0; 3353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendUDPPacket() => transmittedBytes=%d", transmittedBytes); 3357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(const char* fileName, 3362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool loop, 3363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const FileFormats format, 3364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int startPosition, 3365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const float volumeScaling, 3366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int stopPosition, 3367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," 3371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " format=%d, volumeScaling=%5.3f, startPosition=%d, " 3372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 3373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 3374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 3376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 3379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 3380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 33849a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3386b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 3387b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3388b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3389b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3390b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 3391b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3393b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3394b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, (const FileFormats)format); 3395b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3396b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 3397b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3398b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 3399b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 340031d30700d638c4cfa47c26cac7cb00c7232874c9henrike@webrtc.org "StartPlayingFileLocally() filePlayer format is not correct"); 3401b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 3402b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3404b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org const WebRtc_UWord32 notificationTime(0); 3405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3406b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile( 3407b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org fileName, 3408b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org loop, 3409b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org startPosition, 3410b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 3411b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 3412b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, 3413b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const CodecInst*)codecInst) != 0) 3414b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3415b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 3416b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_BAD_FILE, kTraceError, 3417b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to start file playout"); 3418b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 3419b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3420b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 3421b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 3422b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3423b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 3424b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = true; 3425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3426ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 3427ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 3428066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 3429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(InStream* stream, 3434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const FileFormats format, 3435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int startPosition, 3436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const float volumeScaling, 3437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int stopPosition, 3438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(format=%d," 3442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 3443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 3444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 3446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() NULL as input stream"); 3450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlaying) 3455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 3458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 3459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 34639a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3464b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3465b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Destroy the old instance 3466b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 3467b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3468b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3469b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3470b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 3471b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3472b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3473b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Create the instance 3474b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3475b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, 3476b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const FileFormats)format); 3477b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3478b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 3479b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3480b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 3481b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 3482b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFileLocally() filePlayer format isnot correct"); 3483b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 3484b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3485b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3486b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org const WebRtc_UWord32 notificationTime(0); 3487b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3488b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 3489b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 3490b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 3491b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, codecInst) != 0) 3492b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3493b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3494b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to " 3495b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "start file playout"); 3496b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 3497b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3498b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 3499b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 3500b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3501b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 3502b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = true; 3503b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3504ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 3505ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 3506066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 3507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileLocally() 3512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileLocally()"); 3515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFilePlaying) 3517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileLocally() isnot playing"); 3521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 35259a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3526b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 3527b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StopPlayingFile() != 0) 3528b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 3529b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 3530b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 3531b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() could not stop playing"); 3532b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 3533b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 3534b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3535b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3536b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 3537b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlaying = false; 3538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3539b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // _fileCritSect cannot be taken while calling 3540b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // SetAnonymousMixibilityStatus. Refer to comments in 3541b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // StartPlayingFileLocally(const char* ...) for more details. 3542066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) 3543066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org { 3544066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org _engineStatisticsPtr->SetLastError( 3545066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 3546b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() failed to stop participant from playing as" 3547b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "file in the mixer"); 3548066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 3549066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org } 3550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileLocally() const 3555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileLocally()"); 3558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (WebRtc_Word32)_outputFilePlaying; 3560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3562ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.orgint Channel::RegisterFilePlayingToMixer() 3563ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org{ 3564ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // Return success for not registering for file playing to mixer if: 3565ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 1. playing file before playout is started on that channel. 3566ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 2. starting playout without file playing on that channel. 3567ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (!_playing || !_outputFilePlaying) 3568ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 3569ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 3570ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 3571ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 3572ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // |_fileCritSect| cannot be taken while calling 3573ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // SetAnonymousMixabilityStatus() since as soon as the participant is added 3574ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // frames can be pulled by the mixer. Since the frames are generated from 3575ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // the file, _fileCritSect will be taken. This would result in a deadlock. 3576ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) 3577ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 3578ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3579ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlaying = false; 3580ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _engineStatisticsPtr->SetLastError( 3581ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 3582ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org "StartPlayingFile() failed to add participant as file to mixer"); 3583ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 3584ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 3585ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr = NULL; 3586ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 3587ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 3588ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 3589ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 3590ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org} 3591ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 3592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::ScaleLocalFilePlayout(const float scale) 3593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ScaleLocalFilePlayout(scale=%5.3f)", scale); 3596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 35979a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFilePlaying) 3600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "ScaleLocalFilePlayout() isnot playing"); 3604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_outputFilePlayerPtr == NULL) || 3607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_outputFilePlayerPtr->SetAudioScaling(scale) != 0)) 3608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 3611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetAudioScaling() failed to scale the playout"); 3612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::GetLocalPlayoutPosition(int& positionMs) 3619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetLocalPlayoutPosition(position=?)"); 3622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 position; 3624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36259a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 3628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalPlayoutPosition() filePlayer instance doesnot exist"); 3632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr->GetPlayoutPosition(position) != 0) 3636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalPlayoutPosition() failed"); 3640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com positionMs = position; 3643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(const char* fileName, 3648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool loop, 3649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const FileFormats format, 3650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int startPosition, 3651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const float volumeScaling, 3652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int stopPosition, 3653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " 3657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " 3658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 3659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 3660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 3662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 3665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer is playing"); 3666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36699a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 3672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 3673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 3677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 3680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 3682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 3684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 3688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 notificationTime(0); 3692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile( 3694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, 3695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com loop, 3696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, 3697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, 3698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime, 3699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, 3700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const CodecInst*)codecInst) != 0) 3701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start file playout"); 3705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 3706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 3708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 3711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = true; 3712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(InStream* stream, 3717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const FileFormats format, 3718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int startPosition, 3719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const float volumeScaling, 3720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const int stopPosition, 3721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(format=%d, " 3725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 3726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 3727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 3729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone NULL as input stream"); 3733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 3737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 3740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() is playing"); 3741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 37449a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 3747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 3748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 3752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 3755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 3756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 3757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 3759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingInputFile() filePlayer format isnot correct"); 3763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 notificationTime(0); 3767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 3769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, notificationTime, 3770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, codecInst) != 0) 3771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start " 3774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "file playout"); 3775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 3776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 3778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 3782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = true; 3783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileAsMicrophone() 3788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileAsMicrophone()"); 3791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputFilePlaying) 3793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileAsMicrophone() isnot playing"); 3797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38009a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StopPlayingFile() != 0) 3802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 3805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFile() could not stop playing"); 3806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 3809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 3810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 3811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlaying = false; 3812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileAsMicrophone() const 3817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileAsMicrophone()"); 3820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _inputFilePlaying; 3822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::ScaleFileAsMicrophonePlayout(const float scale) 3825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ScaleFileAsMicrophonePlayout(scale=%5.3f)", scale); 3828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38299a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputFilePlaying) 3832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "ScaleFileAsMicrophonePlayout() isnot playing"); 3836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_inputFilePlayerPtr == NULL) || 3840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_inputFilePlayerPtr->SetAudioScaling(scale) != 0)) 3841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 3844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetAudioScaling() failed to scale playout"); 3845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3851813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.orgint Channel::StartRecordingPlayout(const char* fileName, 3852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout(fileName=%s)", fileName); 3856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 3858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 3860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 3861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 3865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 notificationTime(0); // Not supported in VoE 3866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 3867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 386840197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org if ((codecInst != NULL) && 386940197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org ((codecInst->channels < 1) || (codecInst->channels > 2))) 3870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 3873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 3874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 3875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 3877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 3879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 3880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 3882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 3883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 3884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 3886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 3890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38929a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 3895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 3896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 3898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 3900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 3903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 3904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 3905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 3909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile( 3913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, (const CodecInst&)*codecInst, notificationTime) != 0) 3914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingAudioFile() failed to start file recording"); 3918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 3919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 3921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 3924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 3925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartRecordingPlayout(OutStream* stream, 3930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 3931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout()"); 3934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 3936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 3938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 3939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 3943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 notificationTime(0); // Not supported in VoE 3944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 3945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codecInst != NULL && codecInst->channels != 1) 3947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 3950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 3951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 3952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 3954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 3956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 3957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 3959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 3960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 3961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 3963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 3967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39699a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 3972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 3973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 3975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 3977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 3980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 3981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 3982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 3986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, 3990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime) != 0) 3991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 3993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() failed to " 3994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "start file recording"); 3995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 3996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 3997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 3998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 4002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 4003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopRecordingPlayout() 4008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 4010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRecordingPlayout()"); 4011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFileRecording) 4013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), 4015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecordingPlayout() isnot recording"); 4016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40209a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 4021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StopRecording() != 0) 4023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 4026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecording() could not stop recording"); 4027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 4028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 4030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 4031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 4032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 4033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 4038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMixWithMicStatus(bool mix) 4039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mixFileWithMicrophone=mix; 4041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSpeechOutputLevel(WebRtc_UWord32& level) const 4045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word8 currentLevel = _outputAudioLevel.Level(); 4047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com level = static_cast<WebRtc_Word32> (currentLevel); 4048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevel() => level=%u", level); 4051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSpeechOutputLevelFullRange(WebRtc_UWord32& level) const 4056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 currentLevel = _outputAudioLevel.LevelFullRange(); 4058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com level = static_cast<WebRtc_Word32> (currentLevel); 4059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevelFullRange() => level=%u", level); 4062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMute(bool enable) 4067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMute(enable=%d)", enable); 4070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute = enable; 4071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 4075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Mute() const 4076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _mute; 4078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOutputVolumePan(float left, float right) 4082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOutputVolumePan()"); 4085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft = left; 4086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight = right; 4087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOutputVolumePan(float& left, float& right) const 4092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com left = _panLeft; 4094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com right = _panRight; 4095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetOutputVolumePan() => left=%3.2f, right=%3.2f", left, right); 4098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetChannelOutputVolumeScaling(float scaling) 4103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetChannelOutputVolumeScaling()"); 4106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain = scaling; 4107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetChannelOutputVolumeScaling(float& scaling) const 4112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaling = _outputGain; 4114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetChannelOutputVolumeScaling() => scaling=%3.2f", scaling); 4117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_SRTP 4121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EnableSRTPSend( 4124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CipherTypes cipherType, 4125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int cipherKeyLength, 4126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AuthenticationTypes authType, 4127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int authKeyLength, 4128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int authTagLength, 4129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SecurityLevels level, 4130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const unsigned char key[kVoiceEngineMaxSrtpKeyLength], 4131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool useForRTCP) 4132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EnableSRTPSend()"); 4135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41369a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encrypting) 4139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPSend() encryption already enabled"); 4143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (key == NULL) 4147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceWarning, 4150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPSend() invalid key string"); 4151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (((kEncryption == level || 4155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kEncryptionAndAuthentication == level) && 4156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (cipherKeyLength < kVoiceEngineMinSrtpEncryptLength || 4157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cipherKeyLength > kVoiceEngineMaxSrtpEncryptLength)) || 4158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((kAuthentication == level || 4159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kEncryptionAndAuthentication == level) && 4160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kAuthHmacSha1 == authType && 4161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (authKeyLength > kVoiceEngineMaxSrtpAuthSha1Length || 4162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com authTagLength > kVoiceEngineMaxSrtpAuthSha1Length)) || 4163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((kAuthentication == level || 4164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kEncryptionAndAuthentication == level) && 4165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kAuthNull == authType && 4166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (authKeyLength > kVoiceEngineMaxSrtpKeyAuthNullLength || 4167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com authTagLength > kVoiceEngineMaxSrtpTagAuthNullLength))) 4168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPSend() invalid key length(s)"); 4172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_srtpModule.EnableSRTPEncrypt( 4177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !useForRTCP, 4178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::CipherTypes)cipherType, 4179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cipherKeyLength, 4180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::AuthenticationTypes)authType, 4181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com authKeyLength, authTagLength, 4182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::SecurityLevels)level, 4183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com key) == -1) 4184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SRTP_ERROR, kTraceError, 4187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPSend() failed to enable SRTP encryption"); 4188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr == NULL) 4192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = &_srtpModule; 4194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = true; 4196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DisableSRTPSend() 4202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DisableSRTPSend()"); 4205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 42069a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encrypting) 4209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DisableSRTPSend() SRTP encryption already disabled"); 4213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = false; 4217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_srtpModule.DisableSRTPEncrypt() == -1) 4219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SRTP_ERROR, kTraceError, 4222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DisableSRTPSend() failed to disable SRTP encryption"); 4223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_srtpModule.SRTPDecrypt() && !_srtpModule.SRTPEncrypt()) 4227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Both directions are disabled 4229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = NULL; 4230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EnableSRTPReceive( 4237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CipherTypes cipherType, 4238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int cipherKeyLength, 4239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AuthenticationTypes authType, 4240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int authKeyLength, 4241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int authTagLength, 4242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SecurityLevels level, 4243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const unsigned char key[kVoiceEngineMaxSrtpKeyLength], 4244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool useForRTCP) 4245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EnableSRTPReceive()"); 4248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 42499a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_decrypting) 4252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPReceive() SRTP decryption already enabled"); 4256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (key == NULL) 4260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceWarning, 4263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPReceive() invalid key string"); 4264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((((kEncryption == level) || 4268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (kEncryptionAndAuthentication == level)) && 4269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((cipherKeyLength < kVoiceEngineMinSrtpEncryptLength) || 4270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (cipherKeyLength > kVoiceEngineMaxSrtpEncryptLength))) || 4271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (((kAuthentication == level) || 4272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (kEncryptionAndAuthentication == level)) && 4273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (kAuthHmacSha1 == authType) && 4274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((authKeyLength > kVoiceEngineMaxSrtpAuthSha1Length) || 4275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (authTagLength > kVoiceEngineMaxSrtpAuthSha1Length))) || 4276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (((kAuthentication == level) || 4277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (kEncryptionAndAuthentication == level)) && 4278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (kAuthNull == authType) && 4279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ((authKeyLength > kVoiceEngineMaxSrtpKeyAuthNullLength) || 4280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (authTagLength > kVoiceEngineMaxSrtpTagAuthNullLength)))) 4281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPReceive() invalid key length(s)"); 4285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_srtpModule.EnableSRTPDecrypt( 4289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !useForRTCP, 4290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::CipherTypes)cipherType, 4291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com cipherKeyLength, 4292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::AuthenticationTypes)authType, 4293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com authKeyLength, 4294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com authTagLength, 4295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (SrtpModule::SecurityLevels)level, 4296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com key) == -1) 4297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SRTP_ERROR, kTraceError, 4300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "EnableSRTPReceive() failed to enable SRTP decryption"); 4301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr == NULL) 4305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = &_srtpModule; 4307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = true; 4310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DisableSRTPReceive() 4316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DisableSRTPReceive()"); 4319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43209a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_decrypting) 4323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DisableSRTPReceive() SRTP decryption already disabled"); 4327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = false; 4331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_srtpModule.DisableSRTPDecrypt() == -1) 4333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SRTP_ERROR, kTraceError, 4336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DisableSRTPReceive() failed to disable SRTP decryption"); 4337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_srtpModule.SRTPDecrypt() && !_srtpModule.SRTPEncrypt()) 4341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = NULL; 4343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 4349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterExternalEncryption(Encryption& encryption) 4352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalEncryption()"); 4355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43569a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_encryptionPtr) 4359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalEncryption() encryption already enabled"); 4363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = &encryption; 4367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = true; 4369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = true; 4370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalEncryption() 4376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalEncryption()"); 4379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 43809a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_encryptionPtr) 4383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalEncryption() encryption already disabled"); 4387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _decrypting = false; 4391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encrypting = false; 4392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _encryptionPtr = NULL; 4394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventOutband(unsigned char eventCode, 4399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, int attenuationDb, 4400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 4401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", 4404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 4405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent = playDtmfEvent; 4407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 44082853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, 4409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb) != 0) 4410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_DTMF_FAILED, 4413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 4414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendTelephoneEventOutband() failed to send event"); 4415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventInband(unsigned char eventCode, 4421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, 4422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int attenuationDb, 4423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 4424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", 4427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 4428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent = playDtmfEvent; 4430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); 4431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetDtmfPlayoutStatus(bool enable) 4437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetDtmfPlayoutStatus()"); 4440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetDtmfPlayoutStatus(enable) != 0) 4441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 4444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetDtmfPlayoutStatus() failed to set Dtmf playout"); 4445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 4451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DtmfPlayoutStatus() const 4452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _audioCodingModule.DtmfPlayoutStatus(); 4454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendTelephoneEventPayloadType(unsigned char type) 4458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendTelephoneEventPayloadType()"); 4461f81f9f8c2a18fb20ee60406ece45ff3210367ff9andrew@webrtc.org if (type > 127) 4462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTelephoneEventPayloadType() invalid type"); 4466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 44681da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org CodecInst codec; 44691da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.plfreq = 8000; 44701da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.pltype = type; 44711da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org memcpy(codec.plname, "telephone-event", 16); 44722853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 4473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 4476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTelephoneEventPayloadType() failed to register send" 4477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "payload type"); 4478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTelephoneEventPayloadType = type; 4481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendTelephoneEventPayloadType(unsigned char& type) 4486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendTelephoneEventPayloadType()"); 4489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com type = _sendTelephoneEventPayloadType; 4490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTelephoneEventPayloadType() => type=%u", type); 4493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_DTMF_DETECTION 4497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 4499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterTelephoneEventDetection( 4500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TelephoneEventDetectionMethods detectionMethod, 4501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoETelephoneEventObserver& observer) 4502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterTelephoneEventDetection()"); 45059a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_telephoneEventDetectionPtr) 4508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterTelephoneEventDetection() detection already enabled"); 4512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _telephoneEventDetectionPtr = &observer; 4516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (detectionMethod) 4518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kInBand: 4520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandTelephoneEventDetection = true; 4521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outOfBandTelephoneEventDetecion = false; 4522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kOutOfBand: 4524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandTelephoneEventDetection = false; 4525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outOfBandTelephoneEventDetecion = true; 4526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kInAndOutOfBand: 4528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandTelephoneEventDetection = true; 4529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outOfBandTelephoneEventDetecion = true; 4530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 4532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterTelephoneEventDetection() invalid detection method"); 4535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandTelephoneEventDetection) 4539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Enable in-band Dtmf detectin in the ACM. 4541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.RegisterIncomingMessagesCallback(this) != 0) 4542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 4545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterTelephoneEventDetection() failed to enable Dtmf " 4546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "detection"); 4547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Enable/disable out-of-band detection of received telephone-events. 4551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // When enabled, RtpAudioFeedback::OnReceivedTelephoneEvent() will be 4552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // called two times by the RTP/RTCP module (start & end). 4553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool forwardToDecoder = 45542853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->TelephoneEventForwardToDecoder(); 4555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool detectEndOfTone = true; 45562853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetTelephoneEventStatus(_outOfBandTelephoneEventDetecion, 4557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com forwardToDecoder, 4558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com detectEndOfTone); 4559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterTelephoneEventDetection() 4565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterTelephoneEventDetection()"); 4568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 45699a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_telephoneEventDetectionPtr) 4572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, 4575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 4576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterTelephoneEventDetection() detection already disabled"); 4577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Disable out-of-band event detection 4581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool forwardToDecoder = 45822853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->TelephoneEventForwardToDecoder(); 45832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->SetTelephoneEventStatus(false, forwardToDecoder); 4584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Disable in-band Dtmf detection 4586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.RegisterIncomingMessagesCallback(NULL); 4587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandTelephoneEventDetection = false; 4589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outOfBandTelephoneEventDetecion = false; 4590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _telephoneEventDetectionPtr = NULL; 4591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetTelephoneEventDetectionStatus( 4597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool& enabled, 4598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com TelephoneEventDetectionMethods& detectionMethod) 4599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetTelephoneEventDetectionStatus()"); 4602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 46049a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (_telephoneEventDetectionPtr != NULL); 4606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 4609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandTelephoneEventDetection && !_outOfBandTelephoneEventDetecion) 4611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com detectionMethod = kInBand; 4612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (!_inbandTelephoneEventDetection 4613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com && _outOfBandTelephoneEventDetecion) 4614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com detectionMethod = kOutOfBand; 4615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (_inbandTelephoneEventDetection 4616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com && _outOfBandTelephoneEventDetecion) 4617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com detectionMethod = kInAndOutOfBand; 4618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 4621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetTelephoneEventDetectionStatus() => enabled=%d," 4628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "detectionMethod=%d", enabled, detectionMethod); 4629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_DTMF_DETECTION 4633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateRxVadDetection(AudioFrame& audioFrame) 4636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection()"); 4639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int vadDecision = 1; 4641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 464263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; 4643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) 4645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OnRxVadDetected(vadDecision); 4647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _oldVadDecision = vadDecision; 4648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection() => vadDecision=%d", 4652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com vadDecision); 4653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRxVadObserver(VoERxVadCallback &observer) 4658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRxVadObserver()"); 46619a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 4664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRxVadObserver() observer already enabled"); 4668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = &observer; 4671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = true; 4672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRxVadObserver() 4677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRxVadObserver()"); 46809a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rxVadObserverPtr) 4683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRxVadObserver() observer already disabled"); 4687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = NULL; 4690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = false; 4691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::VoiceActivityIndicator(int &activity) 4696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com activity = _sendFrameType; 4698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::VoiceActivityIndicator(indicator=%d)", activity); 4701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_AGC 4705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRxAgcStatus(const bool enable, const AgcModes mode) 4708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcStatus(enable=%d, mode=%d)", 4711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 4712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode(GainControl::kFixedDigital); 4714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 4715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcDefault: 4717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kAdaptiveDigital; 4718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcUnchanged: 4720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = _rxAudioProcessingModulePtr->gain_control()->mode(); 4721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcFixedDigital: 4723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kFixedDigital; 4724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcAdaptiveDigital: 4726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode =GainControl::kAdaptiveDigital; 4727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 4729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 4731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() invalid Agc mode"); 4732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_mode(agcMode) != 0) 4736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc mode"); 4740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->Enable(enable) != 0) 4743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 4747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled = enable; 4751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 4752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcStatus(bool& enabled, AgcModes& mode) 4758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcStatus(enable=?, mode=?)"); 4761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = _rxAudioProcessingModulePtr->gain_control()->is_enabled(); 4763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode = 4764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->mode(); 4765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 4767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (agcMode) 4769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kFixedDigital: 4771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcFixedDigital; 4772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kAdaptiveDigital: 4774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcAdaptiveDigital; 4775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 4777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxAgcStatus() invalid Agc mode"); 4780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRxAgcConfig(const AgcConfig config) 4788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcConfig()"); 4791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_target_level_dbfs( 4793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv) != 0) 4794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set target peak |level|" 4798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "(or envelope) of the Agc"); 4799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->set_compression_gain_db( 4802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB) != 0) 4803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set the range in |gain| the" 4807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " digital compression stage may apply"); 4808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->gain_control()->enable_limiter( 4811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable) != 0) 4812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set hard limiter to the signal"); 4816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcConfig(AgcConfig& config) 4824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcConfig(config=%?)"); 4827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv = 4829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->target_level_dbfs(); 4830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB = 4831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->compression_gain_db(); 4832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable = 4833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->gain_control()->is_limiter_enabled(); 4834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), "GetRxAgcConfig() => " 4837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "targetLeveldBOv=%u, digitalCompressionGaindB=%u," 4838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " limiterEnable=%d", 4839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv, 4840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB, 4841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable); 4842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC 4847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_NR 4849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRxNsStatus(const bool enable, const NsModes mode) 4852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxNsStatus(enable=%d, mode=%d)", 4855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 4856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level nsLevel( 4858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (NoiseSuppression::Level)WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE); 4859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 4860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsDefault: 4863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = (NoiseSuppression::Level) 4864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_VOICE_ENGINE_RX_NS_DEFAULT_MODE; 4865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsUnchanged: 4867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = _rxAudioProcessingModulePtr->noise_suppression()->level(); 4868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsConference: 4870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 4871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsLowSuppression: 4873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kLow; 4874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsModerateSuppression: 4876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kModerate; 4877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsHighSuppression: 4879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 4880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsVeryHighSuppression: 4882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kVeryHigh; 4883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->set_level(nsLevel) 4887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 4888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Ns level"); 4892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxAudioProcessingModulePtr->noise_suppression()->Enable(enable) != 0) 4895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 4898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 4899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxNsIsEnabled = enable; 4903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxApmIsEnabled = ((_rxAgcIsEnabled == true) || (_rxNsIsEnabled == true)); 4904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxNsStatus(bool& enabled, NsModes& mode) 4910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxNsStatus(enable=?, mode=?)"); 4913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = 4915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->noise_suppression()->is_enabled(); 4916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level ncLevel = 4917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAudioProcessingModulePtr->noise_suppression()->level(); 4918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 4920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (ncLevel) 4922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kLow: 4924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsLowSuppression; 4925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kModerate: 4927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsModerateSuppression; 4928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kHigh: 4930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsHighSuppression; 4931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kVeryHigh: 4933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsVeryHighSuppression; 4934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 4935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 4938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 4939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxNsStatus() => enabled=%d, mode=%d", enabled, mode); 4940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_NR 4944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRTPObserver(VoERTPObserver& observer) 4947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 4949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRTPObserver()"); 49509a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtpObserverPtr) 4953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRTPObserver() observer already enabled"); 4957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr = &observer; 4961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserver = true; 4962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRTPObserver() 4968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRTPObserver()"); 49719a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rtpObserverPtr) 4974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 4977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRTPObserver() observer already disabled"); 4978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserver = false; 4982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpObserverPtr = NULL; 4983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 4988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRTCPObserver(VoERTCPObserver& observer) 4989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRTCPObserver()"); 49929a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rtcpObserverPtr) 4995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 4997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 4998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRTCPObserver() observer already enabled"); 4999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr = &observer; 5003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserver = true; 5004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRTCPObserver() 5010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRTCPObserver()"); 50139a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 5014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rtcpObserverPtr) 5016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 5019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRTCPObserver() observer already disabled"); 5020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserver = false; 5024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtcpObserverPtr = NULL; 5025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetLocalSSRC(unsigned int ssrc) 5031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetLocalSSRC()"); 5034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 5035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_SENDING, kTraceError, 5038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() already sending"); 5039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 50412853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSSRC(ssrc) != 0) 5042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() failed to set SSRC"); 5046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetLocalSSRC(unsigned int& ssrc) 5053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 50542853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->SSRC(); 5055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 5057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalSSRC() => ssrc=%lu", ssrc); 5058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteSSRC(unsigned int& ssrc) 5063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 50642853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->RemoteSSRC(); 5065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 5067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteSSRC() => ssrc=%lu", ssrc); 5068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteCSRCs(unsigned int arrCSRC[15]) 5073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (arrCSRC == NULL) 5075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() invalid array argument"); 5079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]; 5082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 CSRCs(0); 50832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org CSRCs = _rtpRtcpModule->CSRCs(arrOfCSRC); 5084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (CSRCs > 0) 5085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com memcpy(arrCSRC, arrOfCSRC, CSRCs * sizeof(WebRtc_UWord32)); 5087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int i = 0; i < (int) CSRCs; i++) 5088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() => arrCSRC[%d]=%lu", i, arrCSRC[i]); 5092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 5094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteCSRCs() => list is empty!"); 5098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return CSRCs; 5100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTPAudioLevelIndicationStatus(bool enable, unsigned char ID) 5104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5105755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc.get() == NULL) 5106755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5107755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc.reset(AudioProcessing::Create(VoEModuleId(_instanceId, 5108755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _channelId))); 5109755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc.get() == NULL) 5110755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5111755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_NO_MEMORY, kTraceCritical, 5112755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Failed to create AudioProcessing"); 5113755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 5114755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5115755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5116755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 5117755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_rtpAudioProc->level_estimator()->Enable(enable) != 5118755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org AudioProcessing::kNoError) 5119755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5120755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _engineStatisticsPtr->SetLastError(VE_APM_ERROR, kTraceWarning, 5121755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Failed to enable AudioProcessing::level_estimator()"); 5122755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5123755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 5124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _includeAudioLevelIndication = enable; 51252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->SetRTPAudioLevelIndicationStatus(enable, ID); 5126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPAudioLevelIndicationStatus(bool& enabled, unsigned char& ID) 5129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 5132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPAudioLevelIndicationStatus() => enabled=%d, ID=%u", 5133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, ID); 51342853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->GetRTPAudioLevelIndicationStatus(enabled, ID); 5135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCPStatus(bool enable) 5139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCPStatus()"); 51422853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPStatus(enable ? 5143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRtcpCompound : kRtcpOff) != 0) 5144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCPStatus() failed to set RTCP status"); 5148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCPStatus(bool& enabled) 5155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 51562853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 5157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (method != kRtcpOff); 5158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 5160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCPStatus() => enabled=%d", enabled); 5161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCP_CNAME(const char cName[256]) 5166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCP_CNAME()"); 51692853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetCNAME(cName) != 0) 5170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCP_CNAME() failed to set RTCP CNAME"); 5174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCP_CNAME(char cName[256]) 5181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 51822853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->CNAME(cName) != 0) 5183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCP_CNAME() failed to retrieve RTCP CNAME"); 5187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCP_CNAME() => cName=%s", cName); 5192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCP_CNAME(char cName[256]) 5197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cName == NULL) 5199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); 5203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5205813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char cname[RTCP_CNAME_SIZE]; 52062853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org const WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 52072853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) 5208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_CNAME, kTraceError, 5211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); 5212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(cName, cname); 5215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() => cName=%s", cName); 5218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCPData( 5223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPHigh, 5224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPLow, 5225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& timestamp, 5226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& playoutTimestamp, 5227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int* jitter, 5228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short* fractionLost) 5229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Information from sender info in received Sender Reports 5231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPSenderInfo senderInfo; 52332853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) 5234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5237fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRemoteRTCPData() failed to retrieve sender info for remote " 5238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "side"); 5239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We only utilize 12 out of 20 bytes in the sender info (ignores packet 5243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and octet count) 5244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh = senderInfo.NTPseconds; 5245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPLow = senderInfo.NTPfraction; 5246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp = senderInfo.RTPtimeStamp; 5247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " 5251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "timestamp=%lu", 5252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh, NTPLow, timestamp); 5253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Locally derived information 5255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This value is updated on each incoming RTCP packet (0 when no packet 5257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has been received) 5258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutTimestamp = _playoutTimeStampRTCP; 5259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => playoutTimestamp=%lu", 5263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playoutTimeStampRTCP); 5264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL != jitter || NULL != fractionLost) 5266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5267ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Get all RTCP receiver report blocks that have been received on this 5268ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // channel. If we receive RTP packets from a remote source we know the 5269ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // remote SSRC and use the report block from him. 5270ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Otherwise use the first report block. 5271ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock> remote_stats; 52722853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || 5273ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remote_stats.empty()) { 5274ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5275ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org VoEId(_instanceId, _channelId), 5276ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org "GetRemoteRTCPData() failed to measure statistics due" 5277ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org " to lack of received RTP and/or RTCP packets"); 5278ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org return -1; 5279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5280ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 52812853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5282ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin(); 5283ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org for (; it != remote_stats.end(); ++it) { 5284ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it->remoteSSRC == remoteSSRC) 5285ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org break; 5286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5287ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 5288ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it == remote_stats.end()) { 5289ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // If we have not received any RTCP packets from this SSRC it probably 5290ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // means that we have not received any RTP packets. 5291ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Use the first received report block instead. 5292ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org it = remote_stats.begin(); 5293ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remoteSSRC = it->remoteSSRC; 5294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5295ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 529679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (jitter) { 529779af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *jitter = it->jitter; 529879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 529979af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 530079af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => jitter = %lu", *jitter); 530179af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 5302ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 530379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (fractionLost) { 530479af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost = it->fractionLost; 530579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 530679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 530779af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => fractionLost = %lu", 530879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost); 530979af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 5310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendApplicationDefinedRTCPPacket(const unsigned char subType, 5316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int name, 5317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* data, 5318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short dataLengthInBytes) 5319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendApplicationDefinedRTCPPacket()"); 5322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_sending) 5323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 5326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() not sending"); 5327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL == data) 5330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid data value"); 5334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (dataLengthInBytes % 4 != 0) 5337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid length value"); 5341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 53432853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod status = _rtpRtcpModule->RTCP(); 5344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status == kRtcpOff) 5345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTCP_ERROR, kTraceError, 5348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() RTCP is disabled"); 5349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create and schedule the RTCP APP packet for transmission 53532853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPApplicationSpecificData( 5354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 5355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 5356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const unsigned char*) data, 5357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataLengthInBytes) != 0) 5358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_ERROR, kTraceError, 5361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); 5362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics( 5369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& averageJitterMs, 5370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& maxJitterMs, 5371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& discardedPackets) 5372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 fraction_lost(0); 5374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 cum_lost(0); 5375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 ext_max(0); 5376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 jitter(0); 5377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 max_jitter(0); 5378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 5380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 53812853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 5382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &cum_lost, 5383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ext_max, 5384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &jitter, 5385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &max_jitter) != 0) 5386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 5389fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to read RTP statistics from the " 5390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP/RTCP module"); 5391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_Word32 playoutFrequency = 5394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioCodingModule.PlayoutFrequency(); 5395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (playoutFrequency > 0) 5396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale RTP statistics given the current playout frequency 5398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com maxJitterMs = max_jitter / (playoutFrequency / 1000); 5399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs = jitter / (playoutFrequency / 1000); 5400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com discardedPackets = _numberOfDiscardedPackets; 5403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => averageJitterMs = %lu, maxJitterMs = %lu," 5407fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " discardedPackets = %lu)", 5408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs, maxJitterMs, discardedPackets); 5409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 54128a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPSenderInfo(SenderInfo* sender_info) { 54138a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (sender_info == NULL) { 54148a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 54158a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPSenderInfo() invalid sender_info."); 54168a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 54178a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 54188a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54198a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the sender info from the latest received RTCP Sender Report. 54208a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org RTCPSenderInfo rtcp_sender_info; 54218a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_sender_info) != 0) { 54228a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 54238a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPSenderInfo() failed to read RTCP SR sender info."); 54248a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 54258a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 54268a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54278a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->NTP_timestamp_high = rtcp_sender_info.NTPseconds; 54288a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->NTP_timestamp_low = rtcp_sender_info.NTPfraction; 54298a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->RTP_timestamp = rtcp_sender_info.RTPtimeStamp; 54308a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->sender_packet_count = rtcp_sender_info.sendPacketCount; 54318a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org sender_info->sender_octet_count = rtcp_sender_info.sendOctetCount; 54328a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 54338a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 54348a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54358a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPReportBlocks( 54368a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<ReportBlock>* report_blocks) { 54378a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (report_blocks == NULL) { 54388a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 54398a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlock()s invalid report_blocks."); 54408a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 54418a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 54428a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54438a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the report blocks from the latest received RTCP Sender or Receiver 54448a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Report. Each element in the vector contains the sender's SSRC and a 54458a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // report block according to RFC 3550. 54468a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock> rtcp_report_blocks; 54478a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) { 54488a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 54498a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlocks() failed to read RTCP SR/RR report block."); 54508a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 54518a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 54528a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54538a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (rtcp_report_blocks.empty()) 54548a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 54558a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 54568a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin(); 54578a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org for (; it != rtcp_report_blocks.end(); ++it) { 54588a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org ReportBlock report_block; 54598a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.sender_SSRC = it->remoteSSRC; 54608a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.source_SSRC = it->sourceSSRC; 54618a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.fraction_lost = it->fractionLost; 54628a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.cumulative_num_packets_lost = it->cumulativeLost; 54638a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.extended_highest_sequence_number = it->extendedHighSeqNum; 54648a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.interarrival_jitter = it->jitter; 54658a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.last_SR_timestamp = it->lastSR; 54668a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.delay_since_last_SR = it->delaySinceLastSR; 54678a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_blocks->push_back(report_block); 54688a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 54698a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 54708a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 54718a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 5472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics(CallStatistics& stats) 5474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 fraction_lost(0); 5476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 cum_lost(0); 5477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 ext_max(0); 5478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 jitter(0); 5479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 max_jitter(0); 5480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part one of the final structure (four values) 5482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 5484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 54852853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->StatisticsRTP(&fraction_lost, 5486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &cum_lost, 5487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &ext_max, 5488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &jitter, 5489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &max_jitter) != 0) 5490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 5493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to read RTP statistics from the " 5494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP/RTCP module"); 5495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost = fraction_lost; 5498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.cumulativeLost = cum_lost; 5499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.extendedMax = ext_max; 5500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples = jitter; 5501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => fractionLost=%lu, cumulativeLost=%lu," 5505fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " extendedMax=%lu, jitterSamples=%li)", 5506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost, stats.cumulativeLost, stats.extendedMax, 5507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples); 5508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part two of the final structure (one value) 5510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 RTT(0); 55122853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 5513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (method == kRtcpOff) 5514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5517fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() RTCP is disabled => valid RTT " 5518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "measurements cannot be retrieved"); 5519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 5520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The remote SSRC will be zero if no RTP packet has been received. 55222853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org WebRtc_UWord32 remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 5523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (remoteSSRC > 0) 5524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 avgRTT(0); 5526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 maxRTT(0); 5527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 minRTT(0); 5528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 55292853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT, &maxRTT) 5530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 5531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5534fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to retrieve RTT from " 5535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP module"); 5536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 5538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5541fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRTPStatistics() failed to measure RTT since no " 5542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTP packets have been received yet"); 5543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.rttMs = static_cast<int> (RTT); 5547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => rttMs=%d", stats.rttMs); 5551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Part three of the final structure (four values) 5553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 bytesSent(0); 5555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 packetsSent(0); 5556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 bytesReceived(0); 5557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 packetsReceived(0); 5558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 55592853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DataCountersRTP(&bytesSent, 5560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &packetsSent, 5561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &bytesReceived, 5562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &packetsReceived) != 0) 5563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to retrieve RTP datacounters =>" 5567fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " output will not be complete"); 5568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent = bytesSent; 5571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsSent = packetsSent; 5572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesReceived = bytesReceived; 5573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived = packetsReceived; 5574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => bytesSent=%d, packetsSent=%d," 5578fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " bytesReceived=%d, packetsReceived=%d)", 5579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent, stats.packetsSent, stats.bytesReceived, 5580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived); 5581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 558542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetFECStatus(bool enable, int redPayloadtype) { 558642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 558742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "Channel::SetFECStatus()"); 558842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 558942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (SetRedPayloadType(redPayloadtype) < 0) { 559042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 559142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 559242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 559342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 559442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 55952cf22a6abce2d38e673505a4cfd5624a3710b5cdperkj@webrtc.org 559642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.SetFECStatus(enable) != 0) { 559742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 559842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 559942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetFECStatus() failed to set FEC state in the ACM"); 560042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 560142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 560242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 5603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetFECStatus(bool& enabled, int& redPayloadtype) 5607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = _audioCodingModule.FECStatus(); 5609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 5610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word8 payloadType(0); 56122853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendREDPayloadType(payloadType) != 0) 5613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() failed to retrieve RED PT from RTP/RTCP " 5617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 5618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() => enabled=%d, redPayloadtype=%d", 5623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, redPayloadtype); 5624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 5627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 5628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetFECStatus() => enabled=%d", enabled); 5629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartRTPDump(const char fileNameUTF8[1024], 5634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTPDirections direction) 5635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRTPDump()"); 5638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 5639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() invalid RTP direction"); 5643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 5647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 5648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 5650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->IsActive()) 5653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpDumpPtr->Stop(); 5655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->Start(fileNameUTF8) != 0) 5657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 5660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() failed to create file"); 5661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopRTPDump(RTPDirections direction) 5668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRTPDump()"); 5671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 5672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRTPDump() invalid RTP direction"); 5676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 5680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 5681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 5683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!rtpDumpPtr->IsActive()) 5686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->Stop(); 5690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 5693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RTPDumpIsActive(RTPDirections direction) 5694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && 5696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (direction != kRtpOutgoing)) 5697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTPDumpIsActive() invalid RTP direction"); 5701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 5702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 5704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 5705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->IsActive(); 5706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertExtraRTPPacket(unsigned char payloadType, 5710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool markerBit, 5711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* payloadData, 5712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short payloadSize) 5713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 5715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::InsertExtraRTPPacket()"); 5716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (payloadType > 127) 5717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_PLTYPE, kTraceError, 5720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload type"); 5721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (payloadData == NULL) 5724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload data"); 5728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 57302853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (payloadSize > _rtpRtcpModule->MaxDataPayloadLength()) 5731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 5734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() invalid payload size"); 5735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_sending) 5738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 5741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() not sending"); 5742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create extra RTP packet by calling RtpRtcp::SendOutgoingData(). 5746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Transport::SendPacket() will be called by the module when the RTP packet 5747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // is created. 5748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The call to SendOutgoingData() does *not* modify the timestamp and 5749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // payloadtype to ensure that the RTP module generates a valid RTP packet 5750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (user might utilize a non-registered payload type). 5751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The marker bit and payload type will be replaced just before the actual 5752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // transmission, i.e., the actual modification is done *after* the RTP 5753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // module has delivered its RTP packet back to the VoE. 5754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will use the stored values above when the packet is modified 5755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (see Channel::SendPacket()). 5756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraPayloadType = payloadType; 5758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _extraMarkerBit = markerBit; 5759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _insertExtraRTPPacket = true; 5760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 57612853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendOutgoingData(kAudioFrameSpeech, 5762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType, 5763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp, 5764ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // Leaving the time when this frame was 5765ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // received from the capture device as 5766ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // undefined for voice for now. 5767ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org -1, 5768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const WebRtc_UWord8*) payloadData, 5769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize) != 0) 5770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 5773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "InsertExtraRTPPacket() failed to send extra RTP packet"); 5774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_UWord32 5781755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.orgChannel::Demultiplex(const AudioFrame& audioFrame) 5782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5784755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Channel::Demultiplex()"); 5785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioFrame = audioFrame; 578663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 5787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_UWord32 57910b0665acc1464d68e878f203bbc8772a0e32402dxians@google.comChannel::PrepareEncodeAndSend(int mixingFrequency) 5792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend()"); 5795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 579663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 5797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 5799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend() invalid audio frame"); 5800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlaying) 5804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MixOrReplaceAudioWithFile(mixingFrequency); 5806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mute) 5809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrameOperations::Mute(_audioFrame); 5811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMedia) 5814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 58159a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 581663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (_audioFrame.num_channels_ == 2); 5817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 5818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr->Process( 5820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 5821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRecordingPerChannel, 582263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org (WebRtc_Word16*)_audioFrame.data_, 582363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.samples_per_channel_, 582463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.sample_rate_hz_, 5825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 5826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com InsertInbandDtmfTone(); 5830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5831755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org if (_includeAudioLevelIndication) 5832755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5833755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org assert(_rtpAudioProc.get() != NULL); 5834755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 5835755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org // Check if settings need to be updated. 583663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->sample_rate_hz() != _audioFrame.sample_rate_hz_) 5837755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 583863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->set_sample_rate_hz(_audioFrame.sample_rate_hz_) != 5839755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org AudioProcessing::kNoError) 5840755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5841755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5842755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org VoEId(_instanceId, _channelId), 5843755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Error setting AudioProcessing sample rate"); 5844755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 5845755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5846755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5847755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 584863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->num_input_channels() != _audioFrame.num_channels_) 5849755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 585063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_rtpAudioProc->set_num_channels(_audioFrame.num_channels_, 585163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.num_channels_) 5852755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org != AudioProcessing::kNoError) 5853755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org { 5854755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 5855755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org VoEId(_instanceId, _channelId), 5856755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Error setting AudioProcessing channels"); 5857755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org return -1; 5858755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5859755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5860755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 5861755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org // Performs level analysis only; does not affect the signal. 5862755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org _rtpAudioProc->ProcessStream(&_audioFrame); 5863755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 5864755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 5865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_UWord32 5869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EncodeAndSend() 5870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 5872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend()"); 5873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 587463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.num_channels_ <= 2); 587563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 5876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 5878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() invalid audio frame"); 5879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 588263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 5883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. 5885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The ACM resamples internally. 588763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.timestamp_ = _timeStamp; 5888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.Add10MsData((AudioFrame&)_audioFrame) != 0) 5889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 5891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() ACM encoding failed"); 5892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 589563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 5896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Encode if complete frame is ready 5898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call will trigger AudioPacketizationCallback::SendData if encoding 5900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // is done and payload is ready for packetization and transmission. 5901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _audioCodingModule.Process(); 5902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::RegisterExternalMediaProcessing( 5905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessingTypes type, 5906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEMediaProcess& processObject) 5907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing()"); 5910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 59119a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 5912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 5914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 5916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 5919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 5920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 5921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = &processObject; 5924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = true; 5925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 5927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 5929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 5932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 5933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 5934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 5935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = &processObject; 5937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia = true; 5938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) 5943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing()"); 5946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 59479a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 5948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 5950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputExternalMediaCallbackPtr) 5952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 5955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 5956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already disabled"); 5957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = false; 5960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = NULL; 5961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 5963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputExternalMediaCallbackPtr) 5965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 5967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 5968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 5969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "input external media already disabled"); 5970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMedia = false; 5973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = NULL; 5974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 5975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 5977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ResetRTCPStatistics() 5981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::ResetRTCPStatistics()"); 5984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 remoteSSRC(0); 59852853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 59862853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org return _rtpRtcpModule->ResetRTT(remoteSSRC); 5987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 5988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 5990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRoundTripTimeSummary(StatVal& delaysMs) const 5991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 5992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 5993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary()"); 5994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Override default module outputs for the case when RTCP is disabled. 5995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is done to ensure that we are backward compatible with the 5996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // VoiceEngine where we did not use RTP/RTCP module. 59972853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (!_rtpRtcpModule->RTCP()) 5998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = -1; 6000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.max = -1; 6001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.average = -1; 6002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary() RTCP is disabled =>" 6004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " valid RTT measurements cannot be retrieved"); 6005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 remoteSSRC; 6009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 RTT; 6010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 avgRTT; 6011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 maxRTT; 6012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 minRTT; 6013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The remote SSRC will be zero if no RTP packet has been received. 60142853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org remoteSSRC = _rtpRtcpModule->RemoteSSRC(); 6015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (remoteSSRC == 0) 6016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRoundTripTimeSummary() unable to measure RTT" 6019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " since no RTP packet has been received yet"); 6020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Retrieve RTT statistics from the RTP/RTCP module for the specified 6023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // channel and SSRC. The SSRC is required to parse out the correct source 6024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // in conference scenarios. 60252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &RTT, &avgRTT, &minRTT,&maxRTT) != 0) 6026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRoundTripTimeSummary unable to retrieve RTT values" 6029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " from the RTCP layer"); 6030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = -1; delaysMs.max = -1; delaysMs.average = -1; 6031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.min = minRTT; 6035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.max = maxRTT; 6036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delaysMs.average = avgRTT; 6037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetworkStatistics(NetworkStatistics& stats) 6043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetworkStatistics()"); 6046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _audioCodingModule.NetworkStatistics( 6047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (ACMNetworkStatistics &)stats); 6048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetDelayEstimate(int& delayMs) const 6052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetDelayEstimate()"); 6055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delayMs = (_averageDelayMs + 5) / 10 + _recPacketDelayMs; 6056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMinimumPlayoutDelay(int delayMs) 6061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMinimumPlayoutDelay()"); 6064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || 6065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) 6066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 6069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() invalid min delay"); 6070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.SetMinimumPlayoutDelay(delayMs) != 0) 6073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 6076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() failed to set min playout delay"); 6077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPlayoutTimestamp(unsigned int& timestamp) 6084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPlayoutTimestamp()"); 6087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 playoutTimestamp(0); 6088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (GetPlayoutTimeStamp(playoutTimestamp) != 0) 6089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_VALUE, kTraceError, 6092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPlayoutTimestamp() failed to retrieve timestamp"); 6093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp = playoutTimestamp; 6096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 6097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 6098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetPlayoutTimestamp() => timestamp=%u", timestamp); 6099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetInitTimestamp(unsigned int timestamp) 6104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitTimestamp()"); 6107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 6108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, "SetInitTimestamp() already sending"); 6111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 61132853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetStartTimestamp(timestamp) != 0) 6114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 6117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitTimestamp() failed to set timestamp"); 6118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetInitSequenceNumber(short sequenceNumber) 6125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitSequenceNumber()"); 6128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_sending) 6129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SENDING, kTraceError, 6132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitSequenceNumber() already sending"); 6133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 61352853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSequenceNumber(sequenceNumber) != 0) 6136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 6138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 6139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetInitSequenceNumber() failed to set sequence number"); 6140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRtpRtcp(RtpRtcp* &rtpRtcpModule) const 6147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRtpRtcp()"); 61502853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org rtpRtcpModule = _rtpRtcpModule.get(); 6151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6154e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use 6155e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// a shared helper. 6156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 61570b0665acc1464d68e878f203bbc8772a0e32402dxians@google.comChannel::MixOrReplaceAudioWithFile(const int mixingFrequency) 6158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6159d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]); 6160e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 6161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 61639a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 6164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 6166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() fileplayer" 6170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " doesnt exist"); 6171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6174d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 6175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 6176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 6177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file mixing " 6181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 6182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fileSamples == 0) 6185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file is ended"); 6189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 619363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == fileSamples); 6194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mixFileWithMicrophone) 6196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6197d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 6198d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 619963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org Utility::MixWithSat(_audioFrame.data_, 6200e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org _audioFrame.num_channels_, 6201d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 6202d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org 1, 6203e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples); 6204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6207d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Replace ACM audio with file. 6208d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 6209d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 6210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioFrame.UpdateFrame(_channelId, 6211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com -1, 6212d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 6213e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples, 6214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency, 6215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kNormalSpeech, 6216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kVadUnknown, 6217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 6218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 6224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::MixAudioWithFile(AudioFrame& audioFrame, 62250b0665acc1464d68e878f203bbc8772a0e32402dxians@google.com const int mixingFrequency) 6226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(mixingFrequency <= 32000); 6228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6229d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org scoped_array<WebRtc_Word16> fileBuffer(new WebRtc_Word16[640]); 6230e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 6231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 62339a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 6234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 6236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 6240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We should get the frequency we ask for. 6244d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 6245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 6246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 6247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 6251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 625563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.samples_per_channel_ == fileSamples) 6256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6257d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 6258d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 625963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org Utility::MixWithSat(audioFrame.data_, 6260e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org audioFrame.num_channels_, 6261d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 6262d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org 1, 6263e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples); 6264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 626863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org "Channel::MixAudioWithFile() samples_per_channel_(%d) != " 6269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "fileSamples(%d)", 627063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, fileSamples); 6271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertInbandDtmfTone() 6279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6280af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Check if we should start a new tone. 6281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfQueue.PendingDtmf() && 6282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !_inbandDtmfGenerator.IsAddingTone() && 6283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.DelaySinceLastTone() > 6284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kMinTelephoneEventSeparationMs) 6285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word8 eventCode(0); 6287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 lengthMs(0); 6288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 attenuationDb(0); 6289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); 6291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); 6292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playInbandDtmfEvent) 6293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add tone to output mixer using a reduced length to minimize 6295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // risk of echo. 6296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, 6297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb); 6298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.IsAddingTone()) 6302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 frequency(0); 6304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.GetSampleRate(frequency); 6305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 630663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (frequency != _audioFrame.sample_rate_hz_) 6307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update sample rate of Dtmf tone since the mixing frequency 6309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has changed. 6310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.SetSampleRate( 631163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org (WebRtc_UWord16) (_audioFrame.sample_rate_hz_)); 6312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset the tone to be added taking the new sample rate into 6313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // account. 6314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.ResetTone(); 6315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6316af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org 6317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word16 toneBuffer[320]; 6318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 toneSamples(0); 6319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms tone segment and set time since last tone to zero 6320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) 6321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() inserting Dtmf failed"); 6325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6328af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Replace mixed audio with DTMF tone. 6329af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org for (int sample = 0; 633063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org sample < _audioFrame.samples_per_channel_; 6331af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org sample++) 6332af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 6333af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org for (int channel = 0; 633463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org channel < _audioFrame.num_channels_; 6335af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org channel++) 6336af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 633763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.data_[sample * _audioFrame.num_channels_ + channel] = 6338af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org toneBuffer[sample]; 6339af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 6340af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 6341af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org 634263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == toneSamples); 6343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 6344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add 10ms to "delay-since-last-tone" counter 6346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.UpdateDelaySinceLastTone(); 6347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 6352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetPlayoutTimeStamp(WebRtc_UWord32& playoutTimestamp) 6353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 timestamp(0); 6355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst currRecCodec; 6356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioCodingModule.PlayoutTimestamp(timestamp) == -1) 6358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPlayoutTimeStamp() failed to read playout" 6361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " timestamp from the ACM"); 6362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 delayMS(0); 6366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_audioDeviceModulePtr->PlayoutDelay(&delayMS) == -1) 6367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 6369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPlayoutTimeStamp() failed to read playout" 6370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " delay from the ADM"); 6371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 playoutFrequency = _audioCodingModule.PlayoutFrequency(); 6375a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org if (_audioCodingModule.ReceiveCodec(currRecCodec) == 0) { 6376a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) { 6377a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org playoutFrequency = 8000; 6378a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) { 6379a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org playoutFrequency = 48000; 6380a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org } 6381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp -= (delayMS * (playoutFrequency/1000)); 6383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutTimestamp = timestamp; 6385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 6387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetPlayoutTimeStamp() => playoutTimestamp = %lu", 6388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playoutTimestamp); 6389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::ResetDeadOrAliveCounters() 6394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections = 0; 6396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections = 0; 6397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateDeadOrAliveCounters(bool alive) 6401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (alive) 6403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countAliveDetections++; 6404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _countDeadDetections++; 6406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 6409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetDeadOrAliveCounters(int& countDead, int& countAlive) const 6410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enabled; 6412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord8 timeSec; 6413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 64142853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, timeSec); 6415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!enabled) 6416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return (-1); 6417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com countDead = static_cast<int> (_countDeadDetections); 6419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com countAlive = static_cast<int> (_countAliveDetections); 6420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 6424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendPacketRaw(const void *data, int len, bool RTCP) 6425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 6427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 6429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!RTCP) 6431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendPacket(_channelId, data, len); 6433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendRTCPPacket(_channelId, data, len); 6437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comWebRtc_Word32 6441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdatePacketDelay(const WebRtc_UWord32 timestamp, 6442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord16 sequenceNumber) 6443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 6445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 6446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp, sequenceNumber); 6447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_Word32 rtpReceiveFrequency(0); 6449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get frequency of last received payload 6451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpReceiveFrequency = _audioCodingModule.ReceiveFrequency(); 6452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst currRecCodec; 6454a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org if (_audioCodingModule.ReceiveCodec(currRecCodec) == 0) { 6455a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org if (STR_CASE_CMP("G722", currRecCodec.plname) == 0) { 6456a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // Even though the actual sampling rate for G.722 audio is 6457a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // 16,000 Hz, the RTP clock rate for the G722 payload format is 6458a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // 8,000 Hz because that value was erroneously assigned in 6459a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // RFC 1890 and must remain unchanged for backward compatibility. 6460a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org rtpReceiveFrequency = 8000; 6461a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org } else if (STR_CASE_CMP("opus", currRecCodec.plname) == 0) { 6462a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // We are resampling Opus internally to 32,000 Hz until all our 6463a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // DSP routines can operate at 48,000 Hz, but the RTP clock 6464a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // rate for the Opus payload format is standardized to 48,000 Hz, 6465a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org // because that is the maximum supported decoding sampling rate. 6466a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org rtpReceiveFrequency = 48000; 6467a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org } 6468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord32 timeStampDiff = timestamp - _playoutTimeStampRTP; 6471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord32 timeStampDiffMs(0); 6472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (timeStampDiff > 0) 6474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6475a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org switch (rtpReceiveFrequency) { 6476a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 8000: 6477a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 3); 6478a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org break; 6479a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 16000: 6480a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 4); 6481a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org break; 6482a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 32000: 6483a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff >> 5); 6484a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org break; 6485a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 48000: 6486a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org timeStampDiffMs = static_cast<WebRtc_UWord32>(timeStampDiff / 48); 6487a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org break; 6488a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org default: 6489a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 6490a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org VoEId(_instanceId, _channelId), 6491a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org "Channel::UpdatePacketDelay() invalid sample rate"); 6492a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org timeStampDiffMs = 0; 6493a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org return -1; 6494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (timeStampDiffMs > 5000) 6496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeStampDiffMs = 0; 6498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_averageDelayMs == 0) 6501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _averageDelayMs = timeStampDiffMs; 6503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Filter average delay value using exponential filter (alpha is 6507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 7/8). We derive 10*_averageDelayMs here (reduces risk of 6508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // rounding error) and compensate for it in GetDelayEstimate() 6509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // later. Adding 4/8 results in correct rounding. 6510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _averageDelayMs = ((_averageDelayMs*7 + 10*timeStampDiffMs + 4)>>3); 6511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (sequenceNumber - _previousSequenceNumber == 1) 6514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WebRtc_UWord16 packetDelayMs = 0; 6516a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org switch (rtpReceiveFrequency) { 6517a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 8000: 6518a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org packetDelayMs = static_cast<WebRtc_UWord16>( 6519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (timestamp - _previousTimestamp) >> 3); 6520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 6521a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 16000: 6522a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org packetDelayMs = static_cast<WebRtc_UWord16>( 6523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (timestamp - _previousTimestamp) >> 4); 6524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 6525a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 32000: 6526a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org packetDelayMs = static_cast<WebRtc_UWord16>( 6527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (timestamp - _previousTimestamp) >> 5); 6528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 6529a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org case 48000: 6530a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org packetDelayMs = static_cast<WebRtc_UWord16>( 6531a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org (timestamp - _previousTimestamp) / 48); 6532a7d8387bdd7f7c8901292ad57eb531aa82cef817tina.legrand@webrtc.org break; 6533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (packetDelayMs >= 10 && packetDelayMs <= 60) 6536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recPacketDelayMs = packetDelayMs; 6537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousSequenceNumber = sequenceNumber; 6541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousTimestamp = timestamp; 6542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 6544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterReceiveCodecsToRTPModule() 6548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 6549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 6550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule()"); 6551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 6554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtc_UWord8 nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 6555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 6557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 6559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_audioCodingModule.Codec(idx, codec) == -1) || 65602853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterReceivePayload(codec) == -1)) 6561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 6563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 6564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 6565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() unable" 6567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " to register %s (%d/%d/%d/%d) to RTP/RTCP receiver", 6568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 6569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 6570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 6572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 6574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceInfo, 6575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 6576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 6577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() %s " 6578fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "(%d/%d/%d/%d) has been added to the RTP/RTCP " 6579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "receiver", 6580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 6581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 6582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 6584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 658650419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgint Channel::ApmProcessRx(AudioFrame& frame) { 658750419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org AudioProcessing* audioproc = _rxAudioProcessingModulePtr; 658850419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org // Register the (possibly new) frame parameters. 658950419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->set_sample_rate_hz(frame.sample_rate_hz_) != 0) { 6590655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR1(LS_WARNING, set_sample_rate_hz, frame.sample_rate_hz_); 659150419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 659250419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->set_num_channels(frame.num_channels_, 659350419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org frame.num_channels_) != 0) { 6594655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR1(LS_WARNING, set_num_channels, frame.num_channels_); 659550419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 659650419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org if (audioproc->ProcessStream(&frame) != 0) { 6597655d8f56f61eef7bd074748e1f6f5c5d2cd767d5andrew@webrtc.org LOG_FERR0(LS_WARNING, ProcessStream); 659850419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org } 659950419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.org return 0; 6600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 6601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 660242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetSecondarySendCodec(const CodecInst& codec, 660342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org int red_payload_type) { 660442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (SetRedPayloadType(red_payload_type) < 0) { 660542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 660642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 660742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 660842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 660942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 661042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.RegisterSecondarySendCodec(codec) < 0) { 661142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 661242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 661342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetSecondarySendCodec() Failed to register secondary send codec in " 661442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "ACM"); 661542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 661642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 661742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 661842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 661942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 662042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 662142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgvoid Channel::RemoveSecondarySendCodec() { 662242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _audioCodingModule.UnregisterSecondarySendCodec(); 662342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 662442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 662542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::GetSecondarySendCodec(CodecInst* codec) { 662642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.SecondarySendCodec(codec) < 0) { 662742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 662842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 662942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "GetSecondarySendCodec() Failed to get secondary sent codec from ACM"); 663042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 663142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 663242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 663342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 663442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 663542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetRedPayloadType(int red_payload_type) { 663642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (red_payload_type < 0) { 663742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 663842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_PLTYPE_ERROR, kTraceError, 663942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() invalid RED paylaod type"); 664042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 664142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 664242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 664342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org CodecInst codec; 664442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org bool found_red = false; 664542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 664642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org // Get default RED settings from the ACM database 664742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org const int num_codecs = AudioCodingModule::NumberOfCodecs(); 664842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org for (int idx = 0; idx < num_codecs; idx++) { 664942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _audioCodingModule.Codec(idx, codec); 665042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!STR_CASE_CMP(codec.plname, "RED")) { 665142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org found_red = true; 665242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org break; 665342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 665442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 665542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 665642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!found_red) { 665742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 665842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 665942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED is not supported"); 666042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 666142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 666242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 666342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org codec.pltype = red_payload_type; 666442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_audioCodingModule.RegisterSendCodec(codec) < 0) { 666542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 666642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 666742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in ACM module failed"); 666842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 666942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 667042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 667142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) { 667242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 667342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 667442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in RTP/RTCP module failed"); 667542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 667642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 667742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 667842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 667942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 6680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} // namespace voe 6681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} // namespace webrtc 6682