10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004 Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_CONFIG_H 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <config.h> 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef HAVE_WEBRTC_VOICE 330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/webrtc/webrtcvoiceengine.h" 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <algorithm> 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <cstdio> 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string> 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <vector> 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 41cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/audiorenderer.h" 42cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/constants.h" 43cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/streamparams.h" 44cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/base/voiceprocessor.h" 45cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/media/webrtc/webrtcvoe.h" 462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/base64.h" 472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/byteorder.h" 482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h" 492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h" 502a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h" 512a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringencode.h" 522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringutils.h" 535528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org#include "webrtc/common.h" 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "webrtc/modules/audio_processing/include/audio_processing.h" 555462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org#include "webrtc/video_engine/include/vie_network.h" 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef WIN32 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <objbase.h> // NOLINT 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstruct CodecPref { 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const char* name; 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int clockrate; 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channels; 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int payload_type; 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool is_multi_rate; 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const CodecPref kCodecPrefs[] = { 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "OPUS", 48000, 2, 111, true }, 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "ISAC", 16000, 1, 103, true }, 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "ISAC", 32000, 1, 104, true }, 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CELT", 32000, 1, 109, true }, 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CELT", 32000, 2, 110, true }, 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "G722", 16000, 1, 9, false }, 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "ILBC", 8000, 1, 102, false }, 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "PCMU", 8000, 1, 0, false }, 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "PCMA", 8000, 1, 8, false }, 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CN", 48000, 1, 107, false }, 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CN", 32000, 1, 106, false }, 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CN", 16000, 1, 105, false }, 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "CN", 8000, 1, 13, false }, 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "red", 8000, 1, 127, false }, 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { "telephone-event", 8000, 1, 126, false }, 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// For Linux/Mac, using the default device is done by specifying index 0 for 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// VoE 4.0 and not -1 (which was the case for VoE 3.5). 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// On Windows Vista and newer, Microsoft introduced the concept of "Default 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Communications Device". This means that there are two types of default 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// devices (old Wave Audio style default and Default Communications Device). 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// On Windows systems which only support Wave Audio style default, uses either 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// -1 or 0 to select the default device. 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// On Windows systems which support both "Default Communication Device" and 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// old Wave Audio style default, use -1 for Default Communications Device and 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// -2 for Wave Audio style default, which is what we want to use for clips. 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// It's not clear yet whether the -2 index is handled properly on other OSes. 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#ifdef WIN32 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kDefaultAudioDeviceId = -1; 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kDefaultSoundclipDeviceId = -2; 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kDefaultAudioDeviceId = 0; 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIsacCodecName[] = "ISAC"; 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kL16CodecName[] = "L16"; 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Codec parameters for Opus. 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kOpusMonoBitrate = 32000; 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Parameter used for NACK. 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This value is equivalent to 5 seconds of audio data at 20 ms per packet. 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kNackMaxPackets = 250; 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kOpusStereoBitrate = 64000; 1197162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// draft-spittka-payload-rtp-opus-03 1207162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// Opus bitrate should be in the range between 6000 and 510000. 1217162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgstatic const int kOpusMinBitrate = 6000; 1227162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgstatic const int kOpusMaxBitrate = 510000; 123ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 12480303b162fe139828d0661df23e03f09126508acwu@webrtc.org// Default audio dscp value. 12580303b162fe139828d0661df23e03f09126508acwu@webrtc.org// See http://tools.ietf.org/html/rfc2474 for details. 12680303b162fe139828d0661df23e03f09126508acwu@webrtc.org// See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 1272a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgstatic const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; 1287162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 129ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org// Ensure we open the file in a writeable path on ChromeOS and Android. This 130ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org// workaround can be removed when it's possible to specify a filename for audio 131ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org// option based AEC dumps. 1327162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// 1337162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// TODO(grunell): Use a string in the options instead of hardcoding it here 1347162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// and let the embedder choose the filename (crbug.com/264223). 1357162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// 136ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org// NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified 137ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org// below. 138ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org#if defined(CHROMEOS) 1397162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgstatic const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; 140ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org#elif defined(ANDROID) 141ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.orgstatic const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; 1427162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org#else 1437162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgstatic const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; 1447162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org#endif 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Dumps an AudioCodec in RFC 2327-ish format. 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic std::string ToString(const AudioCodec& codec) { 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::stringstream ss; 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ss << codec.name << "/" << codec.clockrate << "/" << codec.channels 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " (" << codec.id << ")"; 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ss.str(); 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic std::string ToString(const webrtc::CodecInst& codec) { 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::stringstream ss; 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " (" << codec.pltype << ")"; 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ss.str(); 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgstatic void LogMultiline(rtc::LoggingSeverity sev, char* text) { 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const char* delim = "\r\n"; 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) { 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_V(sev) << tok; 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Severity is an integer because it comes is assumed to be from command line. 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic int SeverityToFilter(int severity) { 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int filter = webrtc::kTraceNone; 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (severity) { 1712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org case rtc::LS_VERBOSE: 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org filter |= webrtc::kTraceAll; 1732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org case rtc::LS_INFO: 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo); 1752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org case rtc::LS_WARNING: 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning); 1772a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org case rtc::LS_ERROR: 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org filter |= (webrtc::kTraceError | webrtc::kTraceCritical); 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return filter; 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool IsCodecMultiRate(const webrtc::CodecInst& codec) { 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) { 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (_stricmp(kCodecPrefs[i].name, codec.plname) == 0 && 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kCodecPrefs[i].clockrate == codec.plfreq) { 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return kCodecPrefs[i].is_multi_rate; 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1937587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.orgstatic bool IsTelephoneEventCodec(const std::string& name) { 1947587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return _stricmp(name.c_str(), "telephone-event") == 0; 1957587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org} 1967587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 1977587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.orgstatic bool IsCNCodec(const std::string& name) { 1987587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return _stricmp(name.c_str(), "CN") == 0; 1997587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org} 2007587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 2017587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.orgstatic bool IsRedCodec(const std::string& name) { 2027587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return _stricmp(name.c_str(), "red") == 0; 2037587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org} 2047587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool FindCodec(const std::vector<AudioCodec>& codecs, 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const AudioCodec& codec, 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AudioCodec* found_codec) { 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != codecs.end(); ++it) { 2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it->Matches(codec)) { 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (found_codec != NULL) { 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *found_codec = *it; 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 219cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool IsNackEnabled(const AudioCodec& codec) { 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kParamValueEmpty)); 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 225cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org// Gets the default set of options applied to the engine. Historically, these 226cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org// were supplied as a combination of flags from the channel manager (ec, agc, 227cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org// ns, and highpass) and the rest hardcoded in InitInternal. 228cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.orgstatic AudioOptions GetDefaultEngineOptions() { 229cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org AudioOptions options; 230cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.echo_cancellation.Set(true); 231cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.auto_gain_control.Set(true); 232cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.noise_suppression.Set(true); 233cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.highpass_filter.Set(true); 234cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.stereo_swapping.Set(false); 235cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.typing_detection.Set(true); 236cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.conference_mode.Set(false); 237cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.adjust_agc_delta.Set(0); 238cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.experimental_agc.Set(false); 239cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.experimental_aec.Set(false); 24070022fa5eb218ec690774cc4a74558699a79600asergeyu@chromium.org options.experimental_ns.Set(false); 241cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org options.aec_dump.Set(false); 242cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org return options; 243cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org} 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass WebRtcSoundclipMedia : public SoundclipMedia { 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org explicit WebRtcSoundclipMedia(WebRtcVoiceEngine *engine) 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : engine_(engine), webrtc_channel_(-1) { 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine_->RegisterSoundclip(this); 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~WebRtcSoundclipMedia() { 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine_->UnregisterSoundclip(this); 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (webrtc_channel_ != -1) { 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We shouldn't have to call Disable() here. DeleteChannel() should call 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // StopPlayout() while deleting the channel. We should fix the bug 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // inside WebRTC and remove the Disable() call bellow. This work is 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // tracked by bug http://b/issue?id=5382855. 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PlaySound(NULL, 0, 0); 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Disable(); 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine_->voe_sc()->base()->DeleteChannel(webrtc_channel_) 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org == -1) { 2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(DeleteChannel, webrtc_channel_); 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool Init() { 26962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org if (!engine_->voe_sc()) { 27062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return false; 27162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org } 27297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org webrtc_channel_ = engine_->CreateSoundclipVoiceChannel(); 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (webrtc_channel_ == -1) { 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(CreateChannel); 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool Enable() { 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine_->voe_sc()->base()->StartPlayout(webrtc_channel_) == -1) { 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StartPlayout, webrtc_channel_); 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool Disable() { 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine_->voe_sc()->base()->StopPlayout(webrtc_channel_) == -1) { 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StopPlayout, webrtc_channel_); 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual bool PlaySound(const char *buf, int len, int flags) { 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The voe file api is not available in chrome. 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!engine_->voe_sc()->file()) { 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Must stop playing the current sound (if any), because we are about to 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // modify the stream. 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine_->voe_sc()->file()->StopPlayingFileLocally(webrtc_channel_) 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org == -1) { 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StopPlayingFileLocally, webrtc_channel_); 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (buf) { 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_.reset(new WebRtcSoundclipStream(buf, len)); 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_->set_loop((flags & SF_LOOP) != 0); 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_->Rewind(); 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Play it. 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine_->voe_sc()->file()->StartPlayingFileLocally( 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc_channel_, stream_.get()) == -1) { 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(StartPlayingFileLocally, webrtc_channel_, stream_.get()); 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Unable to start soundclip"; 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_.reset(); 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int GetLastEngineError() const { return engine_->voe_sc()->error(); } 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org WebRtcVoiceEngine *engine_; 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int webrtc_channel_; 3322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::scoped_ptr<WebRtcSoundclipStream> stream_; 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcVoiceEngine::WebRtcVoiceEngine() 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : voe_wrapper_(new VoEWrapper()), 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_sc_(new VoEWrapper()), 33862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org voe_wrapper_sc_initialized_(false), 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tracing_(new VoETraceWrapper()), 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_(NULL), 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_(NULL), 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org log_filter_(SeverityToFilter(kDefaultLogSeverity)), 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org is_dumping_aec_(false), 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_local_monitor_enable_(false), 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tx_processor_ssrc_(0), 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rx_processor_ssrc_(0) { 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Construct(); 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper, 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoEWrapper* voe_wrapper_sc, 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoETraceWrapper* tracing) 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : voe_wrapper_(voe_wrapper), 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_sc_(voe_wrapper_sc), 35562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org voe_wrapper_sc_initialized_(false), 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tracing_(tracing), 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_(NULL), 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_(NULL), 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org log_filter_(SeverityToFilter(kDefaultLogSeverity)), 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org is_dumping_aec_(false), 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_local_monitor_enable_(false), 362aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org tx_processor_ssrc_(0), 363aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org rx_processor_ssrc_(0) { 364aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org Construct(); 365aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 366aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 367aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgvoid WebRtcVoiceEngine::Construct() { 368aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceFilter(log_filter_); 369aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org initialized_ = false; 370aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; 371aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceOptions(""); 372aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (tracing_->SetTraceCallback(this) == -1) { 373aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0(SetTraceCallback); 374aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 375aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->base()->RegisterVoiceEngineObserver(*this) == -1) { 376aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0(RegisterVoiceEngineObserver); 377aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 378aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Clear the default agc state. 379aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org memset(&default_agc_config_, 0, sizeof(default_agc_config_)); 380aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 381aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Load our audio codec list. 382aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ConstructCodecs(); 383aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 384aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Load our RTP Header extensions. 385aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org rtp_header_extensions_.push_back( 386aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org RtpHeaderExtension(kRtpAudioLevelHeaderExtension, 387aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kRtpAudioLevelHeaderExtensionDefaultId)); 388aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org rtp_header_extensions_.push_back( 389aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, 390aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); 391aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options_ = GetDefaultEngineOptions(); 392aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 393aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 394aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstatic bool IsOpus(const AudioCodec& codec) { 395aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return (_stricmp(codec.name.c_str(), kOpusCodecName) == 0); 396aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 397aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 398aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstatic bool IsIsac(const AudioCodec& codec) { 399aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return (_stricmp(codec.name.c_str(), kIsacCodecName) == 0); 400aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 401aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 402aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// True if params["stereo"] == "1" 403aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstatic bool IsOpusStereoEnabled(const AudioCodec& codec) { 40402632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org int value; 40502632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org return codec.GetParam(kCodecParamStereo, &value) && value == 1; 406aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 407aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 408ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org// TODO(minyue): Clamp bitrate when invalid. 409aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstatic bool IsValidOpusBitrate(int bitrate) { 410aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return (bitrate >= kOpusMinBitrate && bitrate <= kOpusMaxBitrate); 411aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 412aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 413aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// Returns 0 if params[kCodecParamMaxAverageBitrate] is not defined or invalid. 414aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// Returns the value of params[kCodecParamMaxAverageBitrate] otherwise. 415aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstatic int GetOpusBitrateFromParams(const AudioCodec& codec) { 416aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org int bitrate = 0; 417aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { 418aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return 0; 419aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 420aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!IsValidOpusBitrate(bitrate)) { 421aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "Codec parameter \"maxaveragebitrate\" has an " 422aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << "invalid value: " << bitrate; 423aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return 0; 424aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 425aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return bitrate; 426aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 427aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 428621454260f22dfe3709f870c53df5c72e2417607buildbot@webrtc.org// Return true if params[kCodecParamUseInbandFec] == "1", false 42902632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org// otherwise. 43007617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.orgstatic bool IsOpusFecEnabled(const AudioCodec& codec) { 43102632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org int value; 43202632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org return codec.GetParam(kCodecParamUseInbandFec, &value) && value == 1; 43302632fd0ce3e3625079f6472bd55370ed58509debuildbot@webrtc.org} 43407617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org 435ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org// Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not 436ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org// defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. 437ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.orgstatic int GetOpusMaxPlaybackRate(const AudioCodec& codec) { 438ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org int value; 439ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { 440ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org return value; 441ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 442ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org return kOpusDefaultMaxPlaybackRate; 443ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org} 444ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 445ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.orgstatic void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, 446ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org bool* enable_codec_fec, int* max_playback_rate) { 447ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org *enable_codec_fec = IsOpusFecEnabled(codec); 448ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org *max_playback_rate = GetOpusMaxPlaybackRate(codec); 449ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 450ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // If OPUS, change what we send according to the "stereo" codec 451ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // parameter, and not the "channels" parameter. We set 452ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If 453ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // the bitrate is not specified, i.e. is zero, we set it to the 454ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // appropriate default value for mono or stereo Opus. 455ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 456ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // TODO(minyue): The determination of bit rate might take the maximum playback 457ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // rate into account. 458ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 459ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (IsOpusStereoEnabled(codec)) { 460ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org voe_codec->channels = 2; 461ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (!IsValidOpusBitrate(codec.bitrate)) { 462ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (codec.bitrate != 0) { 463ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org LOG(LS_WARNING) << "Overrides the invalid supplied bitrate(" 464ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << codec.bitrate 465ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << ") with default opus stereo bitrate: " 466ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << kOpusStereoBitrate; 467ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 468ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org voe_codec->rate = kOpusStereoBitrate; 469ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 470ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } else { 471ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org voe_codec->channels = 1; 472ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (!IsValidOpusBitrate(codec.bitrate)) { 473ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (codec.bitrate != 0) { 474ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org LOG(LS_WARNING) << "Overrides the invalid supplied bitrate(" 475ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << codec.bitrate 476ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << ") with default opus mono bitrate: " 477ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << kOpusMonoBitrate; 478ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 479ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org voe_codec->rate = kOpusMonoBitrate; 480ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 481ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 482ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org int bitrate_from_params = GetOpusBitrateFromParams(codec); 483ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (bitrate_from_params != 0) { 484ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org voe_codec->rate = bitrate_from_params; 485ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 486ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org} 487ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 488aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgvoid WebRtcVoiceEngine::ConstructCodecs() { 489aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; 490aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); 491aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org for (int i = 0; i < ncodecs; ++i) { 492aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::CodecInst voe_codec; 493aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { 494aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Skip uncompressed formats. 495aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (_stricmp(voe_codec.plname, kL16CodecName) == 0) { 496aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org continue; 497aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 498aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 499aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org const CodecPref* pref = NULL; 500aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org for (size_t j = 0; j < ARRAY_SIZE(kCodecPrefs); ++j) { 501aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (_stricmp(kCodecPrefs[j].name, voe_codec.plname) == 0 && 502aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kCodecPrefs[j].clockrate == voe_codec.plfreq && 503aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kCodecPrefs[j].channels == voe_codec.channels) { 504aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org pref = &kCodecPrefs[j]; 505aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org break; 506aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 507aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 508aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 509aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (pref) { 510aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Use the payload type that we've configured in our pref table; 511aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // use the offset in our pref table to determine the sort order. 512aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq, 513aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_codec.rate, voe_codec.channels, 514aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ARRAY_SIZE(kCodecPrefs) - (pref - kCodecPrefs)); 515aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << ToString(codec); 516aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (IsIsac(codec)) { 517aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Indicate auto-bandwidth in signaling. 518aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org codec.bitrate = 0; 519aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 520aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (IsOpus(codec)) { 521aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Only add fmtp parameters that differ from the spec. 522aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (kPreferredMinPTime != kOpusDefaultMinPTime) { 523aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org codec.params[kCodecParamMinPTime] = 5242a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::ToString(kPreferredMinPTime); 525aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 526aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (kPreferredMaxPTime != kOpusDefaultMaxPTime) { 527aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org codec.params[kCodecParamMaxPTime] = 5282a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::ToString(kPreferredMaxPTime); 529aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 530aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // TODO(hellner): Add ptime, sprop-stereo, stereo and useinbandfec 531aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // when they can be set to values other than the default. 532aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 533aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org codecs_.push_back(codec); 534aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 535aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "Unexpected codec: " << ToString(voe_codec); 536aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 537aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 538aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 539aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Make sure they are in local preference order. 540aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org std::sort(codecs_.begin(), codecs_.end(), &AudioCodec::Preferable); 541aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 542aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 543aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgWebRtcVoiceEngine::~WebRtcVoiceEngine() { 544aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "WebRtcVoiceEngine::~WebRtcVoiceEngine"; 545aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->base()->DeRegisterVoiceEngineObserver() == -1) { 546aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0(DeRegisterVoiceEngineObserver); 547aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 548aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (adm_) { 549aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_.reset(); 550aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org adm_->Release(); 551aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org adm_ = NULL; 552aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 553aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (adm_sc_) { 554aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_.reset(); 555aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org adm_sc_->Release(); 556aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org adm_sc_ = NULL; 557aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 558aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 559aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Test to see if the media processor was deregistered properly 560aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ASSERT(SignalRxMediaFrame.is_empty()); 561aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ASSERT(SignalTxMediaFrame.is_empty()); 562aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 563aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org tracing_->SetTraceCallback(NULL); 564aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 565aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 5662a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool WebRtcVoiceEngine::Init(rtc::Thread* worker_thread) { 567aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtcVoiceEngine::Init"; 568aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool res = InitInternal(); 569aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (res) { 570aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtcVoiceEngine::Init Done!"; 571aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 572aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_ERROR) << "WebRtcVoiceEngine::Init failed"; 573aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org Terminate(); 574aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 575aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return res; 576aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 577aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 578aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::InitInternal() { 579aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Temporarily turn logging level up for the Init call 580aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org int old_filter = log_filter_; 5812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int extended_filter = log_filter_ | SeverityToFilter(rtc::LS_INFO); 582aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceFilter(extended_filter); 583aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceOptions(""); 584aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 585aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Init WebRtc VoiceEngine. 586aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->base()->Init(adm_) == -1) { 587aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0_EX(Init, voe_wrapper_->error()); 588aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceFilter(old_filter); 589aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 590aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 591aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 592aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceFilter(old_filter); 593aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SetTraceOptions(log_options_); 594aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 595aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Log the VoiceEngine version info 596aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org char buffer[1024] = ""; 597aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_->base()->GetVersion(buffer); 598aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtc VoiceEngine Version:"; 5992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org LogMultiline(rtc::LS_INFO, buffer); 600aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 601aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Save the default AGC configuration settings. This must happen before 602aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // calling SetOptions or the default will be overwritten. 603aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->processing()->GetAgcConfig(default_agc_config_) == -1) { 604aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0(GetAgcConfig); 605aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 606aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 607aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 608aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Set defaults for options, so that ApplyOptions applies them explicitly 609aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // when we clear option (channel) overrides. External clients can still 610aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // modify the defaults via SetOptions (on the media engine). 611aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!SetOptions(GetDefaultEngineOptions())) { 612aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 613aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 614aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 615aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Print our codec list again for the call diagnostic log 616aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtc VoiceEngine codecs:"; 617aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs_.begin(); 618aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org it != codecs_.end(); ++it) { 619aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << ToString(*it); 620aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 621aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 622aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Disable the DTMF playout when a tone is sent. 623aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // PlayDtmfTone will be used if local playout is needed. 624aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->dtmf()->SetDtmfFeedbackStatus(false) == -1) { 625aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetDtmfFeedbackStatus, false); 626aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 627aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 628aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org initialized_ = true; 629aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 630aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 631aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 632aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::EnsureSoundclipEngineInit() { 633aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_sc_initialized_) { 634aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 635aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 636aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Note that, if initialization fails, voe_wrapper_sc_initialized_ will still 637aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // be false, so subsequent calls to EnsureSoundclipEngineInit will 638aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // probably just fail again. That's acceptable behavior. 639aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#if defined(LINUX) && !defined(HAVE_LIBPULSE) 640aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_->hw()->SetAudioDeviceLayer(webrtc::kAudioLinuxAlsa); 641aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 642aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 643aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Initialize the VoiceEngine instance that we'll use to play out sound clips. 644aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_sc_->base()->Init(adm_sc_) == -1) { 645aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error()); 646aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 647aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 648aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 649aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // On Windows, tell it to use the default sound (not communication) devices. 650aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // First check whether there is a valid sound device for playback. 651aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // TODO(juberti): Clean this up when we support setting the soundclip device. 652aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#ifdef WIN32 653aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // The SetPlayoutDevice may not be implemented in the case of external ADM. 654aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // TODO(ronghuawu): We should only check the adm_sc_ here, but current 655aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // PeerConnection interface never set the adm_sc_, so need to check both 656aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // in order to determine if the external adm is used. 657aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!adm_ && !adm_sc_) { 658aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org int num_of_devices = 0; 659aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_sc_->hw()->GetNumOfPlayoutDevices(num_of_devices) != -1 && 660aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org num_of_devices > 0) { 661aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_sc_->hw()->SetPlayoutDevice(kDefaultSoundclipDeviceId) 662aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org == -1) { 663aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1_EX(SetPlayoutDevice, kDefaultSoundclipDeviceId, 664aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_->error()); 665aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 666aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 667aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 668aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "No valid sound playout device found."; 669aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 670aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 671aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 672aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_initialized_ = true; 673aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Initialized WebRtc soundclip engine."; 674aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 675aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 676aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 677aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgvoid WebRtcVoiceEngine::Terminate() { 678aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; 679aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org initialized_ = false; 680aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 681aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org StopAecDump(); 682aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 683aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_sc_) { 684aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_initialized_ = false; 685aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_sc_->base()->Terminate(); 686aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 687aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_->base()->Terminate(); 688aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org desired_local_monitor_enable_ = false; 689aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 690aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 691aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgint WebRtcVoiceEngine::GetCapabilities() { 692aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return AUDIO_SEND | AUDIO_RECV; 693aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 694aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 695aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgVoiceMediaChannel *WebRtcVoiceEngine::CreateChannel() { 696aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org WebRtcVoiceMediaChannel* ch = new WebRtcVoiceMediaChannel(this); 697aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!ch->valid()) { 698aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org delete ch; 699aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ch = NULL; 700aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 701aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return ch; 702aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 703aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 704aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgSoundclipMedia *WebRtcVoiceEngine::CreateSoundclip() { 705aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!EnsureSoundclipEngineInit()) { 706aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_ERROR) << "Unable to create soundclip: soundclip engine failed to " 707aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << "initialize."; 708aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return NULL; 709aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 710aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org WebRtcSoundclipMedia *soundclip = new WebRtcSoundclipMedia(this); 711aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!soundclip->Init() || !soundclip->Enable()) { 712aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org delete soundclip; 713aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return NULL; 714aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 715aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return soundclip; 716aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 717aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 718aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { 719aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!ApplyOptions(options)) { 720aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 721aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 722aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options_ = options; 723aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 724aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 725aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 726aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::SetOptionOverrides(const AudioOptions& overrides) { 727aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Setting option overrides: " << overrides.ToString(); 728aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!ApplyOptions(overrides)) { 729aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 730aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 731aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org option_overrides_ = overrides; 732aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 733aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 734aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 735aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::ClearOptionOverrides() { 736aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Clearing option overrides."; 737aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org AudioOptions options = options_; 738aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Only call ApplyOptions if |options_overrides_| contains overrided options. 739aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // ApplyOptions affects NS, AGC other options that is shared between 740aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // all WebRtcVoiceEngineChannels. 741aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (option_overrides_ == AudioOptions()) { 742aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 743aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 744aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 745aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!ApplyOptions(options)) { 746aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 747aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 748aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org option_overrides_ = AudioOptions(); 749aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 750aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 751aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 752aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// AudioOptions defaults are set in InitInternal (for options with corresponding 753aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// MediaEngineInterface flags) and in SetOptions(int) for flagless options. 754aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) { 755aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org AudioOptions options = options_in; // The options are modified below. 756aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // kEcConference is AEC with high suppression. 757aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::EcModes ec_mode = webrtc::kEcConference; 758aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::AecmModes aecm_mode = webrtc::kAecmSpeakerphone; 759aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog; 760aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::NsModes ns_mode = webrtc::kNsHighSuppression; 761aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool aecm_comfort_noise = false; 762aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.aecm_generate_comfort_noise.Get(&aecm_comfort_noise)) { 763aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "Comfort noise explicitly set to " 764aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << aecm_comfort_noise << " (default is false)."; 765aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 766aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 767aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#if defined(IOS) 768aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // On iOS, VPIO provides built-in EC and AGC. 769aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.echo_cancellation.Set(false); 770aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.auto_gain_control.Set(false); 771aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#elif defined(ANDROID) 772aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ec_mode = webrtc::kEcAecm; 773aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 774aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 775aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#if defined(IOS) || defined(ANDROID) 776aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Set the AGC mode for iOS as well despite disabling it above, to avoid 777aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // unsupported configuration errors from webrtc. 778aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org agc_mode = webrtc::kAgcFixedDigital; 779aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.typing_detection.Set(false); 780aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.experimental_agc.Set(false); 781aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.experimental_aec.Set(false); 782aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.experimental_ns.Set(false); 783aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 784aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 785aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Applying audio options: " << options.ToString(); 786aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 787aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org webrtc::VoEAudioProcessing* voep = voe_wrapper_->processing(); 788aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 789aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool echo_cancellation; 790aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.echo_cancellation.Get(&echo_cancellation)) { 791aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetEcStatus(echo_cancellation, ec_mode) == -1) { 792aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR2(SetEcStatus, echo_cancellation, ec_mode); 793aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 794aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 795aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "Echo control set to " << echo_cancellation 796aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << " with mode " << ec_mode; 797aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 798aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#if !defined(ANDROID) 799aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // TODO(ajm): Remove the error return on Android from webrtc. 800aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetEcMetricsStatus(echo_cancellation) == -1) { 801aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetEcMetricsStatus, echo_cancellation); 802aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 803aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 804aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 805aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (ec_mode == webrtc::kEcAecm) { 806aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetAecmMode(aecm_mode, aecm_comfort_noise) != 0) { 807aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR2(SetAecmMode, aecm_mode, aecm_comfort_noise); 808aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 809aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 810aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 811aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 812aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 813aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool auto_gain_control; 814aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.auto_gain_control.Get(&auto_gain_control)) { 815aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetAgcStatus(auto_gain_control, agc_mode) == -1) { 816aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR2(SetAgcStatus, auto_gain_control, agc_mode); 817aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 818aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 819aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "Auto gain set to " << auto_gain_control 820aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << " with mode " << agc_mode; 821aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 822aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 823aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 824aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.tx_agc_target_dbov.IsSet() || 825aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.tx_agc_digital_compression_gain.IsSet() || 826aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.tx_agc_limiter.IsSet()) { 827aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Override default_agc_config_. Generally, an unset option means "leave 828aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // the VoE bits alone" in this function, so we want whatever is set to be 829aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // stored as the new "default". If we didn't, then setting e.g. 830aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // tx_agc_target_dbov would reset digital compression gain and limiter 831aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // settings. 832aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Also, if we don't update default_agc_config_, then adjust_agc_delta 833aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // would be an offset from the original values, and not whatever was set 834aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // explicitly. 835aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.targetLeveldBOv = 836aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.tx_agc_target_dbov.GetWithDefaultIfUnset( 837aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.targetLeveldBOv); 838aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.digitalCompressionGaindB = 839aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.tx_agc_digital_compression_gain.GetWithDefaultIfUnset( 840aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.digitalCompressionGaindB); 841aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.limiterEnable = 842aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org options.tx_agc_limiter.GetWithDefaultIfUnset( 843aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.limiterEnable); 844aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->processing()->SetAgcConfig(default_agc_config_) == -1) { 845aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR3(SetAgcConfig, 846aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.targetLeveldBOv, 847aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.digitalCompressionGaindB, 848aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org default_agc_config_.limiterEnable); 849aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 850aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 851aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 852aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 853aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool noise_suppression; 854aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.noise_suppression.Get(&noise_suppression)) { 855aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetNsStatus(noise_suppression, ns_mode) == -1) { 856aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR2(SetNsStatus, noise_suppression, ns_mode); 857aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 858aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } else { 859aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_VERBOSE) << "Noise suppression set to " << noise_suppression 860aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << " with mode " << ns_mode; 861aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 862aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 863aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 864aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool highpass_filter; 865aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.highpass_filter.Get(&highpass_filter)) { 866aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "High pass filter enabled? " << highpass_filter; 867aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->EnableHighPassFilter(highpass_filter) == -1) { 868aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetHighpassFilterStatus, highpass_filter); 869aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 870aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 871aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 872aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 873aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool stereo_swapping; 874aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.stereo_swapping.Get(&stereo_swapping)) { 875aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Stereo swapping enabled? " << stereo_swapping; 876aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voep->EnableStereoChannelSwapping(stereo_swapping); 877aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->IsStereoChannelSwappingEnabled() != stereo_swapping) { 878aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(EnableStereoChannelSwapping, stereo_swapping); 879aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 880aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 881aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 882aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 883aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool typing_detection; 884aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.typing_detection.Get(&typing_detection)) { 885aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Typing detection is enabled? " << typing_detection; 886aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voep->SetTypingDetectionStatus(typing_detection) == -1) { 887aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // In case of error, log the info and continue 888aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetTypingDetectionStatus, typing_detection); 889aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 890aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 891aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 892aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org int adjust_agc_delta; 893aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.adjust_agc_delta.Get(&adjust_agc_delta)) { 894aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Adjust agc delta is " << adjust_agc_delta; 895aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!AdjustAgcLevel(adjust_agc_delta)) { 896aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 897aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 898aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 899aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 900aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool aec_dump; 901aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.aec_dump.Get(&aec_dump)) { 902aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Aec dump is enabled? " << aec_dump; 903aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (aec_dump) 904aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org StartAecDump(kAecDumpByAudioOptionFilename); 905aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org else 906aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org StopAecDump(); 907aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 908aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 9095592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org webrtc::Config config; 9105592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org 9115592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org experimental_aec_.SetFrom(options.experimental_aec); 912aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool experimental_aec; 9135592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org if (experimental_aec_.Get(&experimental_aec)) { 9145592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org LOG(LS_INFO) << "Experimental aec is enabled? " << experimental_aec; 9155592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org config.Set<webrtc::DelayCorrection>( 9165592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org new webrtc::DelayCorrection(experimental_aec)); 9175592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org } 9185592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org 9195592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 9205592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org experimental_ns_.SetFrom(options.experimental_ns); 9215592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org bool experimental_ns; 9225592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org if (experimental_ns_.Get(&experimental_ns)) { 9235592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org LOG(LS_INFO) << "Experimental ns is enabled? " << experimental_ns; 9245592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org config.Set<webrtc::ExperimentalNs>( 9255592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org new webrtc::ExperimentalNs(experimental_ns)); 9265592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org } 9275592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org#endif 9285592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org 9295592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org // We check audioproc for the benefit of tests, since FakeWebRtcVoiceEngine 9305592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org // returns NULL on audio_processing(). 9315592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org webrtc::AudioProcessing* audioproc = voe_wrapper_->base()->audio_processing(); 9325592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org if (audioproc) { 9335592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org audioproc->SetExtraOptions(config); 9345592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org } 9355592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org 9365592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org#ifndef USE_WEBRTC_DEV_BRANCH 9375592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org bool experimental_ns; 9385592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org if (options.experimental_ns.Get(&experimental_ns)) { 9395592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org LOG(LS_INFO) << "Experimental ns is enabled? " << experimental_ns; 940aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // We check audioproc for the benefit of tests, since FakeWebRtcVoiceEngine 941aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // returns NULL on audio_processing(). 942aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (audioproc) { 9435592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org if (audioproc->EnableExperimentalNs(experimental_ns) == -1) { 9445592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org LOG_RTCERR1(EnableExperimentalNs, experimental_ns); 9455592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org return false; 9465592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org } 9475592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org } else { 9485592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org LOG(LS_VERBOSE) << "Experimental noise suppression set to " 9495592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org << experimental_ns; 950aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 951aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 9525592deb0a050321bf2916fb300f490132dee99edbuildbot@webrtc.org#endif 953aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 954aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org uint32 recording_sample_rate; 955aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.recording_sample_rate.Get(&recording_sample_rate)) { 956aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Recording sample rate is " << recording_sample_rate; 957aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->hw()->SetRecordingSampleRate(recording_sample_rate)) { 958aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetRecordingSampleRate, recording_sample_rate); 959aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 960aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 961aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 962aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org uint32 playout_sample_rate; 963aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (options.playout_sample_rate.Get(&playout_sample_rate)) { 964aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Playout sample rate is " << playout_sample_rate; 965aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->hw()->SetPlayoutSampleRate(playout_sample_rate)) { 966aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetPlayoutSampleRate, playout_sample_rate); 967aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 968aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 969aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 970aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 971aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 972aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 973aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::SetDelayOffset(int offset) { 974aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org voe_wrapper_->processing()->SetDelayOffsetMs(offset); 975aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->processing()->DelayOffsetMs() != offset) { 976aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR1(SetDelayOffsetMs, offset); 977aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return false; 978aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 979aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 980aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org return true; 981aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org} 982aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 983aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgstruct ResumeEntry { 984aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ResumeEntry(WebRtcVoiceMediaChannel *c, bool p, SendFlags s) 985aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org : channel(c), 986aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org playout(p), 987aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org send(s) { 988aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 989aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 990aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org WebRtcVoiceMediaChannel *channel; 991aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool playout; 992aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org SendFlags send; 993aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org}; 994aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 995aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// TODO(juberti): Refactor this so that the core logic can be used to set the 996aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org// soundclip device. At that time, reinstate the soundclip pause/resume code. 997aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.orgbool WebRtcVoiceEngine::SetDevices(const Device* in_device, 998aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org const Device* out_device) { 999aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#if !defined(IOS) 10002a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int in_id = in_device ? rtc::FromString<int>(in_device->id) : 1001aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kDefaultAudioDeviceId; 10022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int out_id = out_device ? rtc::FromString<int>(out_device->id) : 1003aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org kDefaultAudioDeviceId; 1004aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // The device manager uses -1 as the default device, which was the case for 1005aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // VoE 3.5. VoE 4.0, however, uses 0 as the default in Linux and Mac. 1006aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#ifndef WIN32 1007aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (-1 == in_id) { 1008aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org in_id = kDefaultAudioDeviceId; 1009aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1010aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (-1 == out_id) { 1011aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org out_id = kDefaultAudioDeviceId; 1012aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1013aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org#endif 1014aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 1015aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org std::string in_name = (in_id != kDefaultAudioDeviceId) ? 1016aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org in_device->name : "Default device"; 1017aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org std::string out_name = (out_id != kDefaultAudioDeviceId) ? 1018aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org out_device->name : "Default device"; 1019aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_INFO) << "Setting microphone to (id=" << in_id << ", name=" << in_name 1020aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << ") and speaker to (id=" << out_id << ", name=" << out_name 1021aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org << ")"; 1022aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 1023aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // If we're running the local monitor, we need to stop it first. 1024aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org bool ret = true; 1025aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!PauseLocalMonitor()) { 1026aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "Failed to pause local monitor"; 1027aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ret = false; 1028aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1029aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 1030aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Must also pause all audio playback and capture. 1031aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org for (ChannelList::const_iterator i = channels_.begin(); 1032aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org i != channels_.end(); ++i) { 1033aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org WebRtcVoiceMediaChannel *channel = *i; 1034aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!channel->PausePlayout()) { 1035aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "Failed to pause playout"; 1036aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ret = false; 1037aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1038aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!channel->PauseSend()) { 1039aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG(LS_WARNING) << "Failed to pause send"; 1040aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ret = false; 1041aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1042aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1043aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org 1044aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org // Find the recording device id in VoiceEngine and set recording device. 1045aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (!FindWebRtcAudioDeviceId(true, in_name, in_id, &in_id)) { 1046aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ret = false; 1047aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 1048aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (ret) { 1049aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org if (voe_wrapper_->hw()->SetRecordingDevice(in_id) == -1) { 1050aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org LOG_RTCERR2(SetRecordingDevice, in_name, in_id); 1051aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org ret = false; 1052aa0311d805f9d06dd334d9750e42824e93ba707abuildbot@webrtc.org } 10537663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org webrtc::AudioProcessing* ap = voe()->base()->audio_processing(); 10547663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org if (ap) 10557663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org ap->Initialize(); 10560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Find the playout device id in VoiceEngine and set playout device. 10590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!FindWebRtcAudioDeviceId(false, out_name, out_id, &out_id)) { 10600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to find VoiceEngine device id for " << out_name; 10610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 10620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 10640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->hw()->SetPlayoutDevice(out_id) == -1) { 106597fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org LOG_RTCERR2(SetPlayoutDevice, out_name, out_id); 10660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 10670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Resume all audio playback and capture. 10710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelList::const_iterator i = channels_.begin(); 10720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org i != channels_.end(); ++i) { 10730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org WebRtcVoiceMediaChannel *channel = *i; 10740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channel->ResumePlayout()) { 10750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to resume playout"; 10760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 10770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channel->ResumeSend()) { 10790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to resume send"; 10800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 10810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Resume local monitor. 10850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ResumeLocalMonitor()) { 10860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Failed to resume local monitor"; 10870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 10880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 10910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Set microphone to (id=" << in_id <<" name=" << in_name 10920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ") and speaker to (id="<< out_id << " name=" << out_name 10930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ")"; 10940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 10970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else 10980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1099d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org#endif // !IOS 11000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::FindWebRtcAudioDeviceId( 11030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool is_input, const std::string& dev_name, int dev_id, int* rtc_id) { 11040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // In Linux, VoiceEngine uses the same device dev_id as the device manager. 1105d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org#if defined(LINUX) || defined(ANDROID) 11060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *rtc_id = dev_id; 11070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#else 11090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // In Windows and Mac, we need to find the VoiceEngine device id by name 11100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // unless the input dev_id is the default device id. 11110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (kDefaultAudioDeviceId == dev_id) { 11120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *rtc_id = dev_id; 11130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Get the number of VoiceEngine audio devices. 11170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int count = 0; 11180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (is_input) { 11190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == voe_wrapper_->hw()->GetNumOfRecordingDevices(count)) { 11200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(GetNumOfRecordingDevices); 11210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 11240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == voe_wrapper_->hw()->GetNumOfPlayoutDevices(count)) { 11250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(GetNumOfPlayoutDevices); 11260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (int i = 0; i < count; ++i) { 11310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org char name[128]; 11320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org char guid[128]; 11330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (is_input) { 11340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_->hw()->GetRecordingDeviceName(i, name, guid); 11350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "VoiceEngine microphone " << i << ": " << name; 11360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 11370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_->hw()->GetPlayoutDeviceName(i, name, guid); 11380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "VoiceEngine speaker " << i << ": " << name; 11390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string webrtc_name(name); 11420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (dev_name.compare(0, webrtc_name.size(), webrtc_name) == 0) { 11430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *rtc_id = i; 11440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "VoiceEngine cannot find device: " << dev_name; 11480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif 11500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::GetOutputVolume(int* level) { 11530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org unsigned int ulevel; 11540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->volume()->GetSpeakerVolume(ulevel) == -1) { 11550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(GetSpeakerVolume, level); 11560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *level = ulevel; 11590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::SetOutputVolume(int level) { 11630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(level >= 0 && level <= 255); 11640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->volume()->SetSpeakerVolume(level) == -1) { 11650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(SetSpeakerVolume, level); 11660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceEngine::GetInputLevel() { 11720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org unsigned int ulevel; 11730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (voe_wrapper_->volume()->GetSpeechInputLevel(ulevel) != -1) ? 11740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static_cast<int>(ulevel) : -1; 11750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::SetLocalMonitor(bool enable) { 11780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_local_monitor_enable_ = enable; 11790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeLocalMonitor(desired_local_monitor_enable_); 11800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::ChangeLocalMonitor(bool enable) { 11830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The voe file api is not available in chrome. 11840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!voe_wrapper_->file()) { 11850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (enable && !monitor_) { 11880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org monitor_.reset(new WebRtcMonitorStream); 11890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->file()->StartRecordingMicrophone(monitor_.get()) == -1) { 11900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StartRecordingMicrophone, monitor_.get()); 11910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Must call Stop() because there are some cases where Start will report 11920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // failure but still change the state, and if we leave VE in the on state 11930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // then it could crash later when trying to invoke methods on our monitor. 11940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_->file()->StopRecordingMicrophone(); 11950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org monitor_.reset(); 11960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (!enable && monitor_) { 11990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_wrapper_->file()->StopRecordingMicrophone(); 12000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org monitor_.reset(); 12010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 12030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::PauseLocalMonitor() { 12060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeLocalMonitor(false); 12070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::ResumeLocalMonitor() { 12100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeLocalMonitor(desired_local_monitor_enable_); 12110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst std::vector<AudioCodec>& WebRtcVoiceEngine::codecs() { 12140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return codecs_; 12150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::FindCodec(const AudioCodec& in) { 12180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return FindWebRtcCodec(in, NULL); 12190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Get the VoiceEngine codec that matches |in|, with the supplied settings. 12220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::FindWebRtcCodec(const AudioCodec& in, 12230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst* out) { 12240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int ncodecs = voe_wrapper_->codec()->NumOfCodecs(); 12250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (int i = 0; i < ncodecs; ++i) { 12260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst voe_codec; 12270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->codec()->GetCodec(i, voe_codec) != -1) { 12280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, 12290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.rate, voe_codec.channels, 0); 12300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool multi_rate = IsCodecMultiRate(voe_codec); 12310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Allow arbitrary rates for ISAC to be specified. 12320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (multi_rate) { 12330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set codec.bitrate to 0 so the check for codec.Matches() passes. 12340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org codec.bitrate = 0; 12350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (codec.Matches(in)) { 12370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (out) { 12380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Fixup the payload type. 12390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.pltype = in.id; 12400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set bitrate if specified. 12420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (multi_rate && in.bitrate != 0) { 12430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.rate = in.bitrate; 12440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Apply codec-specific settings. 12470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsIsac(codec)) { 12480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If ISAC and an explicit bitrate is not specified, 12490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // enable auto bandwidth adjustment. 12500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.rate = (in.bitrate > 0) ? in.bitrate : -1; 12510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out = voe_codec; 12530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 12550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 12590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst std::vector<RtpHeaderExtension>& 12610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcVoiceEngine::rtp_header_extensions() const { 12620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return rtp_header_extensions_; 12630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::SetLogging(int min_sev, const char* filter) { 12660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // if min_sev == -1, we keep the current log level. 12670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (min_sev >= 0) { 12680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SetTraceFilter(SeverityToFilter(min_sev)); 12690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 12700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org log_options_ = filter; 12710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SetTraceOptions(initialized_ ? log_options_ : ""); 12720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceEngine::GetLastEngineError() { 12750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return voe_wrapper_->error(); 12760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::SetTraceFilter(int filter) { 12790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org log_filter_ = filter; 12800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tracing_->SetTraceFilter(filter); 12810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 12820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 12830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// We suppport three different logging settings for VoiceEngine: 12840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 1. Observer callback that goes into talk diagnostic logfile. 12850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Use --logfile and --loglevel 12860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 12870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 2. Encrypted VoiceEngine log for debugging VoiceEngine. 12880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Use --voice_loglevel --voice_logfilter "tracefile file_name" 12890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 12900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 3. EC log and dump for debugging QualityEngine. 12910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Use --voice_loglevel --voice_logfilter "recordEC file_name" 12920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 12930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// For more details see: "https://sites.google.com/a/google.com/wavelet/Home/ 12940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Magic-Flute--RTC-Engine-/Magic-Flute-Command-Line-Parameters" 12950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::SetTraceOptions(const std::string& options) { 12960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set encrypted trace file. 12970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<std::string> opts; 12982a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::tokenize(options, ' ', '"', '"', &opts); 12990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<std::string>::iterator tracefile = 13000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::find(opts.begin(), opts.end(), "tracefile"); 13010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tracefile != opts.end() && ++tracefile != opts.end()) { 13020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Write encrypted debug output (at same loglevel) to file 13030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // EncryptedTraceFile no longer supported. 13040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tracing_->SetTraceFile(tracefile->c_str()) == -1) { 13050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(SetTraceFile, *tracefile); 13060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 13095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // Allow trace options to override the trace filter. We default 13105c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // it to log_filter_ (as a translation of libjingle log levels) 13115c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // elsewhere, but this allows clients to explicitly set webrtc 13125c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // log levels. 13135c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org std::vector<std::string>::iterator tracefilter = 13145c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org std::find(opts.begin(), opts.end(), "tracefilter"); 13155c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (tracefilter != opts.end() && ++tracefilter != opts.end()) { 13162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (!tracing_->SetTraceFilter(rtc::FromString<int>(*tracefilter))) { 13175c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org LOG_RTCERR1(SetTraceFilter, *tracefilter); 13185c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 13195c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 13205c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org 13210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set AEC dump file 13220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<std::string>::iterator recordEC = 13230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::find(opts.begin(), opts.end(), "recordEC"); 13240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (recordEC != opts.end()) { 13250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++recordEC; 13260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (recordEC != opts.end()) 13270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StartAecDump(recordEC->c_str()); 13280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org else 13290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StopAecDump(); 13300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 13320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 13330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Ignore spammy trace messages, mostly from the stats API when we haven't 13340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// gotten RTCP info yet from the remote side. 13350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::ShouldIgnoreTrace(const std::string& trace) { 13360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static const char* kTracesToIgnore[] = { 13370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "\tfailed to GetReportBlockInformation", 13380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRecCodec() failed to get received codec", 13390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetReceivedRtcpStatistics: Could not get received RTP statistics", 13400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRemoteRTCPData() failed to measure statistics due to lack of received RTP and/or RTCP packets", // NOLINT 13410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRemoteRTCPData() failed to retrieve sender info for remote side", 13420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRTPStatistics() failed to measure RTT since no RTP packets have been received yet", // NOLINT 13430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRTPStatistics() failed to read RTP statistics from the RTP/RTCP module", 13440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRTPStatistics() failed to retrieve RTT from the RTP/RTCP module", 13450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "SenderInfoReceived No received SR", 13460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "StatisticsRTP() no statistics available", 13470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "TransmitMixer::TypingDetection() VE_TYPING_NOISE_WARNING message has been posted", // NOLINT 13480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "TransmitMixer::TypingDetection() pending noise-saturation warning exists", // NOLINT 13490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "GetRecPayloadType() failed to retrieve RX payload type (error=10026)", // NOLINT 13500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "StopPlayingFileAsMicrophone() isnot playing (error=8088)", 13510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org NULL 13520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 13530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (const char* const* p = kTracesToIgnore; *p; ++p) { 13540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (trace.find(*p) != std::string::npos) { 13550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 13560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 13590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 13600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 13610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::Print(webrtc::TraceLevel level, const char* trace, 13620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int length) { 13632a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::LoggingSeverity sev = rtc::LS_VERBOSE; 13640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (level == webrtc::kTraceError || level == webrtc::kTraceCritical) 13652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org sev = rtc::LS_ERROR; 13660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org else if (level == webrtc::kTraceWarning) 13672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org sev = rtc::LS_WARNING; 13680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org else if (level == webrtc::kTraceStateInfo || level == webrtc::kTraceInfo) 13692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org sev = rtc::LS_INFO; 13700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org else if (level == webrtc::kTraceTerseInfo) 13712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org sev = rtc::LS_INFO; 13720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 13730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Skip past boilerplate prefix text 13740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (length < 72) { 13750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string msg(trace, length); 13760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Malformed webrtc log message: "; 13770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_V(sev) << msg; 13780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 13790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string msg(trace + 71, length - 72); 13800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ShouldIgnoreTrace(msg)) { 13810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_V(sev) << "webrtc: " << msg; 13820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 13850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 13860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::CallbackOnError(int channel_num, int err_code) { 13872a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&channels_cs_); 13880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org WebRtcVoiceMediaChannel* channel = NULL; 13890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc = 0; 13900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel " 13910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << channel_num << "."; 13920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (FindChannelAndSsrc(channel_num, &channel, &ssrc)) { 13930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel != NULL); 13940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel->OnError(ssrc, err_code); 13950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 13960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "VoiceEngine channel " << channel_num 13970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " could not be found in channel list when error reported."; 13980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 13990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::FindChannelAndSsrc( 14020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const { 14030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel != NULL && ssrc != NULL); 14040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *channel = NULL; 14060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *ssrc = 0; 14070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Find corresponding channel and ssrc 14080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelList::const_iterator it = channels_.begin(); 14090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != channels_.end(); ++it) { 14100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(*it != NULL); 14110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((*it)->FindSsrc(channel_num, ssrc)) { 14120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *channel = *it; 14130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 14140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 14180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This method will search through the WebRtcVoiceMediaChannels and 14210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// obtain the voice engine's channel number. 14220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::FindChannelNumFromSsrc( 14230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, MediaProcessorDirection direction, int* channel_num) { 14240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel_num != NULL); 14250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(direction == MPD_RX || direction == MPD_TX); 14260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *channel_num = -1; 14280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Find corresponding channel for ssrc. 14290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelList::const_iterator it = channels_.begin(); 14300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != channels_.end(); ++it) { 14310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(*it != NULL); 14320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (direction & MPD_RX) { 14330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *channel_num = (*it)->GetReceiveChannelNum(ssrc); 14340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (*channel_num == -1 && (direction & MPD_TX)) { 14360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *channel_num = (*it)->GetSendChannelNum(ssrc); 14370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (*channel_num != -1) { 14390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 14400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "FindChannelFromSsrc. No Channel Found for Ssrc: " << ssrc; 14430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 14440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel *channel) { 14472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&channels_cs_); 14480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_.push_back(channel); 14490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel *channel) { 14522a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&channels_cs_); 14530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelList::iterator i = std::find(channels_.begin(), 14540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_.end(), 14550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel); 14560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (i != channels_.end()) { 14570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_.erase(i); 14580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::RegisterSoundclip(WebRtcSoundclipMedia *soundclip) { 14620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org soundclips_.push_back(soundclip); 14630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::UnregisterSoundclip(WebRtcSoundclipMedia *soundclip) { 14660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SoundclipList::iterator i = std::find(soundclips_.begin(), 14670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org soundclips_.end(), 14680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org soundclip); 14690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (i != soundclips_.end()) { 14700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org soundclips_.erase(i); 14710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Adjusts the default AGC target level by the specified delta. 14750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// NB: If we start messing with other config fields, we'll want 14760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// to save the current webrtc::AgcConfig as well. 14770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::AdjustAgcLevel(int delta) { 14780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::AgcConfig config = default_agc_config_; 14790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config.targetLeveldBOv -= delta; 14800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Adjusting AGC level from default -" 14820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << default_agc_config_.targetLeveldBOv << "dB to -" 14830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << config.targetLeveldBOv << "dB"; 14840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->processing()->SetAgcConfig(config) == -1) { 14860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(SetAgcConfig, config.targetLeveldBOv); 14870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 14880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 14900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 14910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 14920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm, 14930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::AudioDeviceModule* adm_sc) { 14940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (initialized_) { 14950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init."; 14960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 14970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 14980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (adm_) { 14990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_->Release(); 15000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_ = NULL; 15010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (adm) { 15030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_ = adm; 15040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_->AddRef(); 15050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 15070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (adm_sc_) { 15080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_->Release(); 15090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_ = NULL; 15100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (adm_sc) { 15120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_ = adm_sc; 15130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org adm_sc_->AddRef(); 15140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 15160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 15170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 15182a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool WebRtcVoiceEngine::StartAecDump(rtc::PlatformFile file) { 15192a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org FILE* aec_dump_file_stream = rtc::FdopenPlatformFileForWriting(file); 15201b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org if (!aec_dump_file_stream) { 15211b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org LOG(LS_ERROR) << "Could not open AEC dump file stream."; 15222a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (!rtc::ClosePlatformFile(file)) 15231b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org LOG(LS_WARNING) << "Could not close file."; 15241b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org return false; 15251b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org } 1526f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org StopAecDump(); 15271b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org if (voe_wrapper_->processing()->StartDebugRecording(aec_dump_file_stream) != 1528f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org webrtc::AudioProcessing::kNoError) { 15291b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org LOG_RTCERR0(StartDebugRecording); 15301b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org fclose(aec_dump_file_stream); 1531f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org return false; 1532f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org } 1533f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org is_dumping_aec_ = true; 1534f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org return true; 1535f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org} 1536f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org 15370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::RegisterProcessor( 15380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, 15390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoiceProcessor* voice_processor, 15400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MediaProcessorDirection direction) { 15410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool register_with_webrtc = false; 15420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel_id = -1; 15430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool success = false; 15440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32* processor_ssrc = NULL; 15450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool found_channel = FindChannelNumFromSsrc(ssrc, direction, &channel_id); 15460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voice_processor == NULL || !found_channel) { 15470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Media Processing Registration Failed. ssrc: " << ssrc 15480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " foundChannel: " << found_channel; 15490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 15500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 15520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::ProcessingTypes processing_type; 15530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 15542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&signal_media_critical_); 15550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (direction == MPD_RX) { 15560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type = webrtc::kPlaybackAllChannelsMixed; 15570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (SignalRxMediaFrame.is_empty()) { 15580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org register_with_webrtc = true; 15590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processor_ssrc = &rx_processor_ssrc_; 15600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRxMediaFrame.connect(voice_processor, 15620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &VoiceProcessor::OnFrame); 15630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 15640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type = webrtc::kRecordingPerChannel; 15650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (SignalTxMediaFrame.is_empty()) { 15660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org register_with_webrtc = true; 15670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processor_ssrc = &tx_processor_ssrc_; 15680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalTxMediaFrame.connect(voice_processor, 15700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &VoiceProcessor::OnFrame); 15710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (register_with_webrtc) { 15740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(janahan): when registering consider instantiating a 15750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // a VoeMediaProcess object and not make the engine extend the interface. 15760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe()->media() && voe()->media()-> 15770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RegisterExternalMediaProcessing(channel_id, 15780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type, 15790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *this) != -1) { 15800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Media Processing Registration Succeeded. channel:" 15810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << channel_id; 15820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *processor_ssrc = ssrc; 15830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = true; 15840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 15850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(RegisterExternalMediaProcessing, 15860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_id, 15870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type); 15880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = false; 15890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 15910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we don't have to register with the engine, we just needed to 15920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // connect a new processor, set success to true; 15930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = true; 15940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 15950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return success; 15960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 15970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 15980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::UnregisterProcessorChannel( 15990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MediaProcessorDirection channel_direction, 16000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, 16010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoiceProcessor* voice_processor, 16020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MediaProcessorDirection processor_direction) { 16030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool success = true; 16040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FrameSignal* signal; 16050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::ProcessingTypes processing_type; 16060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32* processor_ssrc = NULL; 16070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel_direction == MPD_RX) { 16080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal = &SignalRxMediaFrame; 16090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type = webrtc::kPlaybackAllChannelsMixed; 16100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processor_ssrc = &rx_processor_ssrc_; 16110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 16120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal = &SignalTxMediaFrame; 16130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type = webrtc::kRecordingPerChannel; 16140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processor_ssrc = &tx_processor_ssrc_; 16150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 16170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int deregister_id = -1; 16180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 16192a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&signal_media_critical_); 16200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((processor_direction & channel_direction) != 0 && !signal->is_empty()) { 16210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal->disconnect(voice_processor); 16220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel_id = -1; 16230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool found_channel = FindChannelNumFromSsrc(ssrc, 16240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_direction, 16250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &channel_id); 16260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (signal->is_empty() && found_channel) { 16270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org deregister_id = channel_id; 16280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (deregister_id != -1) { 16320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe()->media() && 16330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe()->media()->DeRegisterExternalMediaProcessing(deregister_id, 16340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type) != -1) { 16350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *processor_ssrc = 0; 16360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Media Processing DeRegistration Succeeded. channel:" 16370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << deregister_id; 16380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 16390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(DeRegisterExternalMediaProcessing, 16400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org deregister_id, 16410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org processing_type); 16420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = false; 16430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return success; 16460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 16470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 16480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceEngine::UnregisterProcessor( 16490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, 16500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoiceProcessor* voice_processor, 16510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MediaProcessorDirection direction) { 16520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool success = true; 16530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voice_processor == NULL) { 16540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Media Processing Deregistration Failed. ssrc: " 16550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ssrc; 16560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 16570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!UnregisterProcessorChannel(MPD_RX, ssrc, voice_processor, direction)) { 16590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = false; 16600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!UnregisterProcessorChannel(MPD_TX, ssrc, voice_processor, direction)) { 16620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org success = false; 16630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return success; 16650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 16660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 16670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Implementing method from WebRtc VoEMediaProcess interface 16680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Do not lock mux_channel_cs_ in this callback. 16690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::Process(int channel, 16700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::ProcessingTypes type, 16710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int16_t audio10ms[], 16720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int length, 16730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int sampling_freq, 16740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool is_stereo) { 16752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&signal_media_critical_); 16760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AudioFrame frame(audio10ms, length, sampling_freq, is_stereo); 16770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (type == webrtc::kPlaybackAllChannelsMixed) { 16780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRxMediaFrame(rx_processor_ssrc_, MPD_RX, &frame); 16790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (type == webrtc::kRecordingPerChannel) { 16800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalTxMediaFrame(tx_processor_ssrc_, MPD_TX, &frame); 16810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 16820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Media Processing invoked unexpectedly." 16830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " channel: " << channel << " type: " << type 16840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " tx_ssrc: " << tx_processor_ssrc_ 16850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " rx_ssrc: " << rx_processor_ssrc_; 16860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 16880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 16890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::StartAecDump(const std::string& filename) { 16900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!is_dumping_aec_) { 16910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Start dumping AEC when we are not dumping. 16920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->processing()->StartDebugRecording( 16930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org filename.c_str()) != webrtc::AudioProcessing::kNoError) { 1694f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org LOG_RTCERR1(StartDebugRecording, filename.c_str()); 16950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 16960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org is_dumping_aec_ = true; 16970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 16990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 17000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 17010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceEngine::StopAecDump() { 17020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (is_dumping_aec_) { 17030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Stop dumping AEC when we are dumping. 17040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (voe_wrapper_->processing()->StopDebugRecording() != 17050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::AudioProcessing::kNoError) { 17060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(StopDebugRecording); 17070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 17080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org is_dumping_aec_ = false; 17090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 17100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 17110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 171297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.orgint WebRtcVoiceEngine::CreateVoiceChannel(VoEWrapper* voice_engine_wrapper) { 171397fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org return voice_engine_wrapper->base()->CreateChannel(voe_config_); 171497fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org} 171597fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org 171697fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.orgint WebRtcVoiceEngine::CreateMediaVoiceChannel() { 171797fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org return CreateVoiceChannel(voe_wrapper_.get()); 171897fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org} 171997fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org 172097fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.orgint WebRtcVoiceEngine::CreateSoundclipVoiceChannel() { 172197fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org return CreateVoiceChannel(voe_wrapper_sc_.get()); 172297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org} 172397fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org 1724b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.orgclass WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer 1725b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org : public AudioRenderer::Sink { 1726b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org public: 1727b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org WebRtcVoiceChannelRenderer(int ch, 1728b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org webrtc::AudioTransport* voe_audio_transport) 1729b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org : channel_(ch), 1730b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org voe_audio_transport_(voe_audio_transport), 1731b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer_(NULL) { 1732b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1733b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org virtual ~WebRtcVoiceChannelRenderer() { 1734b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org Stop(); 1735b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1736b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1737b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Starts the rendering by setting a sink to the renderer to get data 1738b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // callback. 1739e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // This method is called on the libjingle worker thread. 1740b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // TODO(xians): Make sure Start() is called only once. 1741b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org void Start(AudioRenderer* renderer) { 17422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&lock_); 1743b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ASSERT(renderer != NULL); 1744e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (renderer_ != NULL) { 1745b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ASSERT(renderer_ == renderer); 1746b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org return; 1747b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1748b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1749b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // TODO(xians): Remove AddChannel() call after Chrome turns on APM 1750b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // in getUserMedia by default. 1751b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer->AddChannel(channel_); 1752b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer->SetSink(this); 1753b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer_ = renderer; 1754b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1755b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1756b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Stops rendering by setting the sink of the renderer to NULL. No data 1757b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // callback will be received after this method. 1758e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // This method is called on the libjingle worker thread. 1759b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org void Stop() { 17602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&lock_); 1761e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org if (renderer_ == NULL) 1762b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org return; 1763b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1764b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer_->RemoveChannel(channel_); 1765b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer_->SetSink(NULL); 1766b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org renderer_ = NULL; 1767b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1768b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1769b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // AudioRenderer::Sink implementation. 1770e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // This method is called on the audio thread. 1771b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org virtual void OnData(const void* audio_data, 1772b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int bits_per_sample, 1773b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int sample_rate, 1774b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int number_of_channels, 1775b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int number_of_frames) OVERRIDE { 1776e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org voe_audio_transport_->OnData(channel_, 1777e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org audio_data, 1778e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org bits_per_sample, 1779e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org sample_rate, 1780e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org number_of_channels, 1781e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org number_of_frames); 1782e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org } 1783e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 1784e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // Callback from the |renderer_| when it is going away. In case Start() has 1785e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // never been called, this callback won't be triggered. 1786e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org virtual void OnClose() OVERRIDE { 17872a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&lock_); 1788e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // Set |renderer_| to NULL to make sure no more callback will get into 1789e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // the renderer. 1790e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org renderer_ = NULL; 1791b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 1792b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1793b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Accessor to the VoE channel ID. 1794b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int channel() const { return channel_; } 1795b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1796b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org private: 1797b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org const int channel_; 1798b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org webrtc::AudioTransport* const voe_audio_transport_; 1799b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 1800b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler. 1801b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // PeerConnection will make sure invalidating the pointer before the object 1802b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // goes away. 1803b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org AudioRenderer* renderer_; 1804e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org 1805e8b0cc3bf706964d657fdb25f0c5791c5a7aa3d7henrike@webrtc.org // Protects |renderer_| in Start(), Stop() and OnClose(). 18062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CriticalSection lock_; 18077162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org}; 18087162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 18090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// WebRtcVoiceMediaChannel 18100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine *engine) 18110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : WebRtcMediaChannel<VoiceMediaChannel, WebRtcVoiceEngine>( 18120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine, 181397fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org engine->CreateMediaVoiceChannel()), 1814cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org send_bw_setting_(false), 1815cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org send_bw_bps_(0), 18160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org options_(), 18170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org dtmf_allowed_(false), 18180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_playout_(false), 18190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org nack_enabled_(false), 18200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org playout_(false), 18214ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org typing_noise_detected_(false), 18220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_send_(SEND_NOTHING), 18230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_(SEND_NOTHING), 18245462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_(NULL), 18255462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_channel_(-1), 18260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default_receive_ssrc_(0) { 18270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine->RegisterChannel(this); 18280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " 18290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << voe_channel(); 18300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1831f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ConfigureSendChannel(voe_channel()); 18320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 18330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { 18350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " 18360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << voe_channel(); 1837d7afd1f0d8473565079f8f17de76607691161dc9buildbot@webrtc.org SetupSharedBandwidthEstimation(NULL, -1); 18380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1839f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Remove any remaining send streams, the default channel will be deleted 1840f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // later. 1841f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org while (!send_channels_.empty()) 1842f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org RemoveSendStream(send_channels_.begin()->first); 18430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Unregister ourselves from the engine. 18450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->UnregisterChannel(this); 18460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Remove any remaining streams. 18477162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org while (!receive_channels_.empty()) { 18487162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org RemoveRecvStream(receive_channels_.begin()->first); 18490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 18500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1851f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Delete the default channel. 1852f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org DeleteChannel(voe_channel()); 18530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 18540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { 18560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Setting voice channel options: " 18570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << options.ToString(); 18580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 185980303b162fe139828d0661df23e03f09126508acwu@webrtc.org // Check if DSCP value is changed from previous. 186080303b162fe139828d0661df23e03f09126508acwu@webrtc.org bool dscp_option_changed = (options_.dscp != options.dscp); 186180303b162fe139828d0661df23e03f09126508acwu@webrtc.org 1862f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // TODO(xians): Add support to set different options for different send 1863f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // streams after we support multiple APMs. 1864f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 18650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We retain all of the existing options, and apply the given ones 18660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // on top. This means there is no way to "clear" options such that 18670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // they go back to the engine default. 18680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org options_.SetAll(options); 18690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_ != SEND_NOTHING) { 18710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!engine()->SetOptionOverrides(options_)) { 18720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << 18730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "Failed to engine SetOptionOverrides during channel SetOptions."; 18740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 18750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 18760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 18770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Will be interpreted when appropriate. 18780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 18790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 18805c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // Receiver-side auto gain control happens per channel, so set it here from 18815c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // options. Note that, like conference mode, setting it on the engine won't 18825c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // have the desired effect, since voice channels don't inherit options from 18835c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // the media engine when those options are applied per-channel. 18845c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org bool rx_auto_gain_control; 18855c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (options.rx_auto_gain_control.Get(&rx_auto_gain_control)) { 18865c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (engine()->voe()->processing()->SetRxAgcStatus( 18875c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org voe_channel(), rx_auto_gain_control, 18885c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org webrtc::kAgcFixedDigital) == -1) { 18895c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control); 18905c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org return false; 18915c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } else { 18925c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control 18935c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org << " with mode " << webrtc::kAgcFixedDigital; 18945c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 18955c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 18965c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (options.rx_agc_target_dbov.IsSet() || 18975c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org options.rx_agc_digital_compression_gain.IsSet() || 18985c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org options.rx_agc_limiter.IsSet()) { 18995c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org webrtc::AgcConfig config; 19005c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // If only some of the options are being overridden, get the current 19015c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org // settings for the channel and bail if they aren't available. 19025c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (!options.rx_agc_target_dbov.IsSet() || 19035c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org !options.rx_agc_digital_compression_gain.IsSet() || 19045c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org !options.rx_agc_limiter.IsSet()) { 19055c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (engine()->voe()->processing()->GetRxAgcConfig( 19065c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org voe_channel(), config) != 0) { 19075c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org LOG(LS_ERROR) << "Failed to get default rx agc configuration for " 19085c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org << "channel " << voe_channel() << ". Since not all rx " 19095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org << "agc options are specified, unable to safely set rx " 19105c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org << "agc options."; 19115c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org return false; 19125c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 19135c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 19145c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.targetLeveldBOv = 19155c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org options.rx_agc_target_dbov.GetWithDefaultIfUnset( 19165c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.targetLeveldBOv); 19175c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.digitalCompressionGaindB = 19185c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org options.rx_agc_digital_compression_gain.GetWithDefaultIfUnset( 19195c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.digitalCompressionGaindB); 19205c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.limiterEnable = options.rx_agc_limiter.GetWithDefaultIfUnset( 19215c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.limiterEnable); 19225c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org if (engine()->voe()->processing()->SetRxAgcConfig( 19235c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org voe_channel(), config) == -1) { 19245c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org LOG_RTCERR4(SetRxAgcConfig, voe_channel(), config.targetLeveldBOv, 19255c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org config.digitalCompressionGaindB, config.limiterEnable); 19265c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org return false; 19275c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 19285c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org } 192980303b162fe139828d0661df23e03f09126508acwu@webrtc.org if (dscp_option_changed) { 19302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; 19318485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org if (options_.dscp.GetWithDefaultIfUnset(false)) 193280303b162fe139828d0661df23e03f09126508acwu@webrtc.org dscp = kAudioDscpValue; 193380303b162fe139828d0661df23e03f09126508acwu@webrtc.org if (MediaChannel::SetDscp(dscp) != 0) { 193480303b162fe139828d0661df23e03f09126508acwu@webrtc.org LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; 193580303b162fe139828d0661df23e03f09126508acwu@webrtc.org } 193680303b162fe139828d0661df23e03f09126508acwu@webrtc.org } 19375c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org 19385462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org // Force update of Video Engine BWE forwarding to reflect experiment setting. 19395462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (!SetupSharedBandwidthEstimation(shared_bwe_vie_, 19405462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_channel_)) { 19415462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 19425462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 19435462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org 19440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Set voice channel options. Current options: " 19450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << options_.ToString(); 19460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 19470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 19480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 19490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetRecvCodecs( 19500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::vector<AudioCodec>& codecs) { 19510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set the payload types to be used for incoming media. 19520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Setting receive voice codecs:"; 19530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 19540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<AudioCodec> new_codecs; 19550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Find all new codecs. We allow adding new codecs but don't allow changing 19560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the payload type of codecs that is already configured since we might 19570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // already be receiving packets with that payload type. 19580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); 19597162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != codecs.end(); ++it) { 19600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AudioCodec old_codec; 19610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (FindCodec(recv_codecs_, *it, &old_codec)) { 19620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (old_codec.id != it->id) { 19630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << it->name << " payload type changed."; 19640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 19650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 19660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 19670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org new_codecs.push_back(*it); 19680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 19690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 19700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (new_codecs.empty()) { 19710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // There are no new codecs to configure. Already configured codecs are 19720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // never removed. 19730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 19740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 19750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 19760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (playout_) { 19770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Receive codecs can not be changed while playing. So we temporarily 19780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // pause playout. 19790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PausePlayout(); 19800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 19810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 19827162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org bool ret = true; 19830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = new_codecs.begin(); 19840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != new_codecs.end() && ret; ++it) { 19850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst voe_codec; 19860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->FindWebRtcCodec(*it, &voe_codec)) { 19870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << ToString(*it); 19880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.pltype = it->id; 19897162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (default_receive_ssrc_ == 0) { 19907162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Set the receive codecs on the default channel explicitly if the 19917162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // default channel is not used by |receive_channels_|, this happens in 19927162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // conference mode or in non-conference mode when there is no playout 19937162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // channel. 19947162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // TODO(xians): Figure out how we use the default channel in conference 19957162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // mode. 19967162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (engine()->voe()->codec()->SetRecPayloadType( 19977162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org voe_channel(), voe_codec) == -1) { 19987162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec)); 19997162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org ret = false; 20007162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 20010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set the receive codecs on all receiving channels. 20047162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::iterator it = receive_channels_.begin(); 20057162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end() && ret; ++it) { 20060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->codec()->SetRecPayloadType( 2007b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org it->second->channel(), voe_codec) == -1) { 2008b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org LOG_RTCERR2(SetRecPayloadType, it->second->channel(), 20097162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org ToString(voe_codec)); 20100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 20110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 20140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Unknown codec " << ToString(*it); 20150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = false; 20160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ret) { 20190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org recv_codecs_ = codecs; 20200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (desired_playout_ && !playout_) { 20230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ResumePlayout(); 20240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 20260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 20270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetSendCodecs( 2029952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org int channel, const std::vector<AudioCodec>& codecs) { 203007617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org // Disable VAD, FEC, and RED unless we know the other side wants them. 2031952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org engine()->voe()->codec()->SetVADStatus(channel, false); 2032952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); 203307617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 203407617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org engine()->voe()->rtp()->SetREDStatus(channel, false); 203507617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org engine()->voe()->codec()->SetFECStatus(channel, false); 203607617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#else 203707617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org // TODO(minyue): Remove code under #else case after new WebRTC roll. 2038952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org engine()->voe()->rtp()->SetFECStatus(channel, false); 203907617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#endif // USE_WEBRTC_DEV_BRANCH 20400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Scan through the list to figure out the codec to use for sending, along 20420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // with the proper configuration for VAD and DTMF. 20437587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org bool found_send_codec = false; 20440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst send_codec; 20450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org memset(&send_codec, 0, sizeof(send_codec)); 20460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2047a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org bool nack_enabled = nack_enabled_; 2048c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org bool enable_codec_fec = false; 2049a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org 2050ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // max_playback_rate <= 0 will not trigger setting of maximum encoding 2051ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // bandwidth. 2052ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org int max_playback_rate = 0; 2053ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 20547587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Set send codec (the first non-telephone-event/CN codec) 20550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); 20560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != codecs.end(); ++it) { 20570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Ignore codecs we don't know about. The negotiation step should prevent 20580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // this, but double-check to be sure. 20590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst voe_codec; 20600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { 20618485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org LOG(LS_WARNING) << "Unknown codec " << ToString(*it); 20620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 20630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 20640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20657587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (IsTelephoneEventCodec(it->name) || IsCNCodec(it->name)) { 20667587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Skip telephone-event/CN codec, which will be handled later. 20677587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org continue; 20687587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 20697587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 20700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 20717587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // We'll use the first codec in the list to actually send audio data. 20727587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Be sure to use the payload type requested by the remote side. 207307617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org // "red", for RED audio, is a special case where the actual codec to be 20747587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // used is specified in params. 20757587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (IsRedCodec(it->name)) { 20767587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Parse out the RED parameters. If we fail, just ignore RED; 20777587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // we don't support all possible params/usage scenarios. 20787587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (!GetRedSendCodec(*it, codecs, &send_codec)) { 20797587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org continue; 20807587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 20817587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 20827587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Enable redundant encoding of the specified codec. Treat any 20837587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // failure as a fatal internal error. 208407617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 208507617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org LOG(LS_INFO) << "Enabling RED on channel " << channel; 208607617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org if (engine()->voe()->rtp()->SetREDStatus(channel, true, it->id) == -1) { 208707617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org LOG_RTCERR3(SetREDStatus, channel, true, it->id); 208807617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#else 208907617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org // TODO(minyue): Remove code under #else case after new WebRTC roll. 20907587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org LOG(LS_INFO) << "Enabling FEC"; 20917587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (engine()->voe()->rtp()->SetFECStatus(channel, true, it->id) == -1) { 20927587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org LOG_RTCERR3(SetFECStatus, channel, true, it->id); 209307617d70029b9232bf7a5d8af375a3ac18a03836buildbot@webrtc.org#endif // USE_WEBRTC_DEV_BRANCH 20947587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return false; 20957587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 20967587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } else { 20977587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org send_codec = voe_codec; 2098a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org nack_enabled = IsNackEnabled(*it); 2099ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // For Opus as the send codec, we are to enable inband FEC if requested 2100ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // and set maximum playback rate. 2101ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (IsOpus(*it)) { 2102ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org GetOpusConfig(*it, &send_codec, &enable_codec_fec, &max_playback_rate); 2103ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 21047587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 21057587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org found_send_codec = true; 21067587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org break; 21077587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 21087587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 2109a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org if (nack_enabled_ != nack_enabled) { 2110a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org SetNack(channel, nack_enabled); 2111a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org nack_enabled_ = nack_enabled; 2112a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org } 2113a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org 21147587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (!found_send_codec) { 21157587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org LOG(LS_WARNING) << "Received empty list of codecs."; 21167587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return false; 21177587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 21187587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 21197587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Set the codec immediately, since SetVADStatus() depends on whether 21207587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // the current codec is mono or stereo. 21217587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (!SetSendCodec(channel, send_codec)) 21227587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org return false; 21237587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 2124c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org // FEC should be enabled after SetSendCodec. 2125c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org if (enable_codec_fec) { 2126c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " 2127c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org << channel; 2128c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 2129c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org if (engine()->voe()->codec()->SetFECStatus(channel, true) == -1) { 2130c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org // Enable codec internal FEC. Treat any failure as fatal internal error. 2131c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org LOG_RTCERR2(SetFECStatus, channel, true); 2132c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org return false; 2133c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org } 2134c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org#endif // USE_WEBRTC_DEV_BRANCH 2135c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org } 2136c547a07407ddf9d3bb52be8874eec40f47889413buildbot@webrtc.org 2137ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // maxplaybackrate should be set after SetSendCodec. 2138ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (max_playback_rate > 0) { 2139ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org LOG(LS_INFO) << "Attempt to set maximum playback rate to " 2140ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << max_playback_rate 2141ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << " Hz on channel " 2142ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org << channel; 2143ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 2144ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org // (max_playback_rate + 1) >> 1 is to obtain ceil(max_playback_rate / 2.0). 2145ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org if (engine()->voe()->codec()->SetOpusMaxPlaybackRate( 2146ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org channel, max_playback_rate) == -1) { 2147ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org LOG(LS_WARNING) << "Could not set maximum playback rate."; 2148ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 2149ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org#endif 2150ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org } 2151ded08bf766f814b46b099c7949f9c9e1726a6adebuildbot@webrtc.org 21527587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Always update the |send_codec_| to the currently set send codec. 21537587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org send_codec_.reset(new webrtc::CodecInst(send_codec)); 21547587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 21557587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (send_bw_setting_) { 21567587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org SetSendBandwidthInternal(send_bw_bps_); 21577587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 21587587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 21597587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Loop through the codecs list again to config the telephone-event/CN codec. 21607587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); 21617587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org it != codecs.end(); ++it) { 21627587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Ignore codecs we don't know about. The negotiation step should prevent 21637587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // this, but double-check to be sure. 21647587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org webrtc::CodecInst voe_codec; 21657587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (!engine()->FindWebRtcCodec(*it, &voe_codec)) { 21667587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org LOG(LS_WARNING) << "Unknown codec " << ToString(*it); 21677587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org continue; 21687587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } 21697587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org 2170f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Find the DTMF telephone event "codec" and tell VoiceEngine channels 2171f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // about it. 21727587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org if (IsTelephoneEventCodec(it->name)) { 2173952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (engine()->voe()->dtmf()->SetSendTelephoneEventPayloadType( 2174952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org channel, it->id) == -1) { 2175952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG_RTCERR2(SetSendTelephoneEventPayloadType, channel, it->id); 2176952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org return false; 21770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 21787587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org } else if (IsCNCodec(it->name)) { 21797587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Turn voice activity detection/comfort noise on if supported. 21807587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // Set the wideband CN payload type appropriately. 21817587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org // (narrowband always uses the static payload type 13). 21820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::PayloadFrequencies cn_freq; 21830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (it->clockrate) { 21840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case 8000: 21850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org cn_freq = webrtc::kFreq8000Hz; 21860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 21870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case 16000: 21880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org cn_freq = webrtc::kFreq16000Hz; 21890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 21900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case 32000: 21910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org cn_freq = webrtc::kFreq32000Hz; 21920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 21930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 21940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "CN frequency " << it->clockrate 21950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " not supported."; 21960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 21970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2198952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Set the CN payloadtype and the VAD status. 2199952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // The CN payload type for 8000 Hz clockrate is fixed at 13. 2200952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (cn_freq != webrtc::kFreq8000Hz) { 2201952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (engine()->voe()->codec()->SetSendCNPayloadType( 2202952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org channel, it->id, cn_freq) == -1) { 2203952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG_RTCERR3(SetSendCNPayloadType, channel, it->id, cn_freq); 2204952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // TODO(ajm): This failure condition will be removed from VoE. 2205952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Restore the return here when we update to a new enough webrtc. 2206952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // 2207952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Not returning false because the SetSendCNPayloadType will fail if 2208952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // the channel is already sending. 2209952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // This can happen if the remote description is applied twice, for 2210952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // example in the case of ROAP on top of JSEP, where both side will 2211952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // send the offer. 22120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2213952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 2214952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Only turn on VAD if we have a CN payload type that matches the 2215952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // clockrate for the codec we are going to use. 2216952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (it->clockrate == send_codec.plfreq) { 2217952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG(LS_INFO) << "Enabling VAD"; 2218952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { 2219952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG_RTCERR2(SetVADStatus, channel, true); 2220952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org return false; 22210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 22220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 22230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2224cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org } 2225952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org return true; 2226952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org} 2227952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org 2228952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.orgbool WebRtcVoiceMediaChannel::SetSendCodecs( 2229952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org const std::vector<AudioCodec>& codecs) { 2230952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org dtmf_allowed_ = false; 2231952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org for (std::vector<AudioCodec>::const_iterator it = codecs.begin(); 2232952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org it != codecs.end(); ++it) { 2233952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Find the DTMF telephone event "codec". 2234952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (_stricmp(it->name.c_str(), "telephone-event") == 0 || 2235952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org _stricmp(it->name.c_str(), "audio/telephone-event") == 0) { 2236952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org dtmf_allowed_ = true; 2237952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 2238952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 2239952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org 2240952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Cache the codecs in order to configure the channel created later. 2241952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org send_codecs_ = codecs; 2242952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org for (ChannelMap::iterator iter = send_channels_.begin(); 2243952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org iter != send_channels_.end(); ++iter) { 2244b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!SetSendCodecs(iter->second->channel(), codecs)) { 22450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2246952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 22470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 22480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2249a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org // Set nack status on receive channels and update |nack_enabled_|. 2250952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org SetNack(receive_channels_, nack_enabled_); 22510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 22520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2253f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2254f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgvoid WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels, 2255f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org bool nack_enabled) { 2256f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::const_iterator it = channels.begin(); 2257f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org it != channels.end(); ++it) { 2258b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org SetNack(it->second->channel(), nack_enabled); 2259f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2260f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 2261f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2262952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.orgvoid WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { 22630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (nack_enabled) { 2264952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG(LS_INFO) << "Enabling NACK for channel " << channel; 22650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); 22660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2267952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org LOG(LS_INFO) << "Disabling NACK for channel " << channel; 22680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); 22690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 22700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 22710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 22720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetSendCodec( 22730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const webrtc::CodecInst& send_codec) { 22740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Selected voice codec " << ToString(send_codec) 22750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ", bitrate=" << send_codec.rate; 2276f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::iterator iter = send_channels_.begin(); 2277f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org iter != send_channels_.end(); ++iter) { 2278b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!SetSendCodec(iter->second->channel(), send_codec)) 2279f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 22800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2281f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2282f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return true; 2283f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 2284f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2285f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgbool WebRtcVoiceMediaChannel::SetSendCodec( 2286f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int channel, const webrtc::CodecInst& send_codec) { 2287f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " 2288f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org << ToString(send_codec) << ", bitrate=" << send_codec.rate; 2289f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2290a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org webrtc::CodecInst current_codec; 2291a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && 2292a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org (send_codec == current_codec)) { 2293a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org // Codec is already configured, we can return without setting it again. 2294a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org return true; 2295a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org } 2296a32dfc68b5624bdc8e3901c1a91adb869f919ef8wu@webrtc.org 2297f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { 2298f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); 2299f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2300f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 23010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 23020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 23030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 23040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( 23050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 23062ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (receive_extensions_ == extensions) { 23072ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return true; 23082ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23092ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23102ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // The default channel may or may not be in |receive_channels_|. Set the rtp 23112ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // header extensions for default channel regardless. 23122ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { 23132ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return false; 23142ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23153ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org 23163ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org // Loop through all receive channels and enable/disable the extensions. 23173ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org for (ChannelMap::const_iterator channel_it = receive_channels_.begin(); 23183ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org channel_it != receive_channels_.end(); ++channel_it) { 23192ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetChannelRecvRtpHeaderExtensions(channel_it->second->channel(), 23202ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org extensions)) { 23213ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return false; 23223ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 23233ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 23242ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23252ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org receive_extensions_ = extensions; 23260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 23270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 23280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 23292ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.orgbool WebRtcVoiceMediaChannel::SetChannelRecvRtpHeaderExtensions( 23302ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org int channel_id, const std::vector<RtpHeaderExtension>& extensions) { 23313ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org const RtpHeaderExtension* audio_level_extension = 23323ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); 23333ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org if (!SetHeaderExtension( 23342ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org &webrtc::VoERTP_RTCP::SetReceiveAudioLevelIndicationStatus, channel_id, 23353ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org audio_level_extension)) { 23363ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return false; 23373ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 23382ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23392ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org const RtpHeaderExtension* send_time_extension = 23402ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); 23413ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org if (!SetHeaderExtension( 23422ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, 23433ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org send_time_extension)) { 23443ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return false; 23453ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 23462ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return true; 23472ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org} 23482ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23492ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.orgbool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( 23502ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org const std::vector<RtpHeaderExtension>& extensions) { 23512ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (send_extensions_ == extensions) { 23522ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return true; 23532ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23542ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23552ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // The default channel may or may not be in |send_channels_|. Set the rtp 23562ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // header extensions for default channel regardless. 23572ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23582ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { 23592ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return false; 23602ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 23622ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // Loop through all send channels and enable/disable the extensions. 23633ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org for (ChannelMap::const_iterator channel_it = send_channels_.begin(); 23643ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org channel_it != send_channels_.end(); ++channel_it) { 23652ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetChannelSendRtpHeaderExtensions(channel_it->second->channel(), 23662ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org extensions)) { 23673ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return false; 23683ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 23690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 23702ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23712ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org send_extensions_ = extensions; 23722ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return true; 23732ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org} 23742ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23752ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.orgbool WebRtcVoiceMediaChannel::SetChannelSendRtpHeaderExtensions( 23762ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org int channel_id, const std::vector<RtpHeaderExtension>& extensions) { 23772ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org const RtpHeaderExtension* audio_level_extension = 23782ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); 23792ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23802ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetHeaderExtension( 23812ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org &webrtc::VoERTP_RTCP::SetSendAudioLevelIndicationStatus, channel_id, 23822ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org audio_level_extension)) { 23832ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return false; 23842ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23852ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23862ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org const RtpHeaderExtension* send_time_extension = 23872ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); 23882ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetHeaderExtension( 23892ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org &webrtc::VoERTP_RTCP::SetSendAbsoluteSenderTimeStatus, channel_id, 23902ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org send_time_extension)) { 23912ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return false; 23922ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 23932ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 23940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 23950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 23960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 23970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetPlayout(bool playout) { 23980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_playout_ = playout; 23990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangePlayout(desired_playout_); 24000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::PausePlayout() { 24030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangePlayout(false); 24040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::ResumePlayout() { 24070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangePlayout(desired_playout_); 24080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { 24110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (playout_ == playout) { 24120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 24130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24157162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Change the playout of all channels to the new state. 24160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool result = true; 24177162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (receive_channels_.empty()) { 24180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Only toggle the default channel if we don't have any other channels. 24190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = SetPlayout(voe_channel(), playout); 24200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24217162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::iterator it = receive_channels_.begin(); 24227162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end() && result; ++it) { 2423b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!SetPlayout(it->second->channel(), playout)) { 24247162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " 2425b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org << it->second->channel() << " failed"; 24260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = false; 24270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (result) { 24310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org playout_ = playout; 24320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return result; 24340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetSend(SendFlags send) { 24370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org desired_send_ = send; 2438f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (!send_channels_.empty()) 24390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeSend(desired_send_); 24400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 24410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::PauseSend() { 24440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeSend(SEND_NOTHING); 24450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::ResumeSend() { 24480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ChangeSend(desired_send_); 24490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 24500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 24510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::ChangeSend(SendFlags send) { 24520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_ == send) { 24530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 24540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2456f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Change the settings on each send channel. 2457f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (send == SEND_MICROPHONE) 24580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->SetOptionOverrides(options_); 24590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2460f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Change the settings on each send channel. 2461f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::iterator iter = send_channels_.begin(); 2462f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org iter != send_channels_.end(); ++iter) { 2463b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!ChangeSend(iter->second->channel(), send)) 24640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2465f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2466f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2467f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Clear up the options after stopping sending. 2468f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (send == SEND_NOTHING) 2469f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->ClearOptionOverrides(); 2470f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2471f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org send_ = send; 2472f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return true; 2473f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 2474f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2475f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgbool WebRtcVoiceMediaChannel::ChangeSend(int channel, SendFlags send) { 2476f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (send == SEND_MICROPHONE) { 2477f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->base()->StartSend(channel) == -1) { 2478f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR1(StartSend, channel); 24790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 24800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->file() && 2482f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->voe()->file()->StopPlayingFileAsMicrophone(channel) == -1) { 2483f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR1(StopPlayingFileAsMicrophone, channel); 24840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 24850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 24860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { // SEND_NOTHING 2487f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ASSERT(send == SEND_NOTHING); 2488f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->base()->StopSend(channel) == -1) { 2489f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR1(StopSend, channel); 2490f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 24910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2492f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 24930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2494f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return true; 2495f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 2496f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 24972ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org// TODO(ronghuawu): Change this method to return bool. 2498f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgvoid WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { 2499f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->network()->RegisterExternalTransport( 2500f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel, *this) == -1) { 2501f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR2(RegisterExternalTransport, channel, this); 25020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2503f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2504f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Enable RTCP (for quality stats and feedback messages) 2505f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org EnableRtcp(channel); 2506f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2507f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Reset all recv codecs; they will be enabled via SetRecvCodecs. 2508f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ResetRecvCodecs(channel); 25092ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 25102ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // Set RTP header extension for the new channel. 25112ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org SetChannelSendRtpHeaderExtensions(channel, send_extensions_); 2512f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org} 2513f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2514f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.orgbool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { 2515f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { 2516f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR1(DeRegisterExternalTransport, channel); 2517f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2518f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2519f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->base()->DeleteChannel(channel) == -1) { 2520f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR1(DeleteChannel, channel); 2521f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2522f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2523f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 25240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 25250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 25260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 25270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { 2528f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // If the default channel is already used for sending create a new channel 2529f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // otherwise use the default channel for sending. 2530f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int channel = GetSendChannelNum(sp.first_ssrc()); 2531f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (channel != -1) { 2532f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); 25330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 25340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 25350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2536f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org bool default_channel_is_available = true; 2537f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::const_iterator iter = send_channels_.begin(); 2538f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org iter != send_channels_.end(); ++iter) { 2539b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (IsDefaultChannel(iter->second->channel())) { 2540f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org default_channel_is_available = false; 2541f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org break; 2542f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2543f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2544f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (default_channel_is_available) { 2545f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel = voe_channel(); 2546f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } else { 2547f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Create a new channel for sending audio data. 254897fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org channel = engine()->CreateMediaVoiceChannel(); 2549f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (channel == -1) { 2550f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR0(CreateChannel); 2551f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2552f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2553f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2554f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ConfigureSendChannel(channel); 2555f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2556f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2557f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Save the channel to send_channels_, so that RemoveSendStream() can still 2558f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // delete the channel in case failure happens below. 2559b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org webrtc::AudioTransport* audio_transport = 2560b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org engine()->voe()->base()->audio_transport(); 2561b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org send_channels_.insert(std::make_pair( 2562b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org sp.first_ssrc(), 2563b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org new WebRtcVoiceChannelRenderer(channel, audio_transport))); 2564f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2565f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Set the send (local) SSRC. 2566f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // If there are multiple send SSRCs, we can only set the first one here, and 2567f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // the rest of the SSRC(s) need to be set after SetSendCodec has been called 2568f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // (with a codec requires multiple SSRC(s)). 2569f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->rtp()->SetLocalSSRC(channel, sp.first_ssrc()) == -1) { 2570f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); 25710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 25720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2573f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2574f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // At this point the channel's local SSRC has been updated. If the channel is 2575f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // the default channel make sure that all the receive channels are updated as 2576f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // well. Receive channels have to have the same SSRC as the default channel in 2577f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // order to send receiver reports with this SSRC. 2578f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (IsDefaultChannel(channel)) { 2579f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::const_iterator it = receive_channels_.begin(); 2580f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org it != receive_channels_.end(); ++it) { 2581f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Only update the SSRC for non-default channels. 2582b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!IsDefaultChannel(it->second->channel())) { 2583b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (engine()->voe()->rtp()->SetLocalSSRC(it->second->channel(), 2584f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sp.first_ssrc()) != 0) { 2585b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org LOG_RTCERR2(SetLocalSSRC, it->second->channel(), sp.first_ssrc()); 2586f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2587f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 25887162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 25890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 25900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 25910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2592f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { 25935462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); 25945462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 25950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 25960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2597952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org // Set the current codecs to be used for the new channel. 2598952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) 2599f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 26007162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 2601f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return ChangeSend(channel, desired_send_); 26020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 26030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 26040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::RemoveSendStream(uint32 ssrc) { 2605f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChannelMap::iterator it = send_channels_.find(ssrc); 2606f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (it == send_channels_.end()) { 2607f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc 2608f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org << " which doesn't exist."; 26090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 26100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 26117162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 2612b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int channel = it->second->channel(); 2613f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChangeSend(channel, SEND_NOTHING); 2614f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2615b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Delete the WebRtcVoiceChannelRenderer object connected to the channel, 2616b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // this will disconnect the audio renderer with the send channel. 2617b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org delete it->second; 2618b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org send_channels_.erase(it); 2619f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2620f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (IsDefaultChannel(channel)) { 2621f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Do not delete the default channel since the receive channels depend on 2622f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // the default channel, recycle it instead. 2623f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChangeSend(channel, SEND_NOTHING); 2624f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } else { 2625f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Clean up and delete the send channel. 2626f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_INFO) << "Removing audio send stream " << ssrc 2627f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org << " with VoiceEngine channel #" << channel << "."; 2628f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (!DeleteChannel(channel)) 2629f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2630f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 2631f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 2632f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (send_channels_.empty()) 2633f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChangeSend(SEND_NOTHING); 26347162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 26350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 26360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 26370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 26380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { 26392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&receive_channels_cs_); 26400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 26410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!VERIFY(sp.ssrcs.size() == 1)) 26420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 26430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc = sp.first_ssrc(); 26440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2645861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org if (ssrc == 0) { 2646861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; 2647861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org return false; 2648861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org } 2649861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org 26507162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (receive_channels_.find(ssrc) != receive_channels_.end()) { 26517162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; 26520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 26530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 26540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 26557162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Reuse default channel for recv stream in non-conference mode call 26567162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // when the default channel is not being used. 2657b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org webrtc::AudioTransport* audio_transport = 2658b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org engine()->voe()->base()->audio_transport(); 26597162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (!InConferenceMode() && default_receive_ssrc_ == 0) { 26607162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_INFO) << "Recv stream " << sp.first_ssrc() 26617162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org << " reuse default channel"; 26627162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org default_receive_ssrc_ = sp.first_ssrc(); 26637162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org receive_channels_.insert(std::make_pair( 2664b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org default_receive_ssrc_, 2665b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org new WebRtcVoiceChannelRenderer(voe_channel(), audio_transport))); 26665462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (!SetupSharedBweOnChannel(voe_channel())) { 26675462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 26685462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 26697162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return SetPlayout(voe_channel(), playout_); 26707162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 26717162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 26720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Create a new channel for receiving audio data. 267397fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org int channel = engine()->CreateMediaVoiceChannel(); 26740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel == -1) { 26750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(CreateChannel); 26760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 26770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 26780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2679861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org if (!ConfigureRecvChannel(channel)) { 2680861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org DeleteChannel(channel); 2681861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org return false; 2682861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org } 2683861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org 2684861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org receive_channels_.insert( 2685b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org std::make_pair( 2686b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ssrc, new WebRtcVoiceChannelRenderer(channel, audio_transport))); 2687861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org 2688861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org LOG(LS_INFO) << "New audio stream " << ssrc 2689861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org << " registered to VoiceEngine channel #" 2690861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org << channel << "."; 2691861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org return true; 2692861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org} 2693861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org 2694861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.orgbool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { 26950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Configure to use external transport, like our default channel. 26960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->network()->RegisterExternalTransport( 26970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel, *this) == -1) { 26980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(SetExternalTransport, channel, this); 26990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 27000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 27020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Use the same SSRC as our default channel (so the RTCP reports are correct). 27038485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org unsigned int send_ssrc = 0; 27040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); 27050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) { 27068485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org LOG_RTCERR1(GetSendSSRC, channel); 27070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 27080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { 27108485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org LOG_RTCERR1(SetSendSSRC, channel); 27110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 27120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 27140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Use the same recv payload types as our default channel. 27150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ResetRecvCodecs(channel); 27160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!recv_codecs_.empty()) { 27170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AudioCodec>::const_iterator it = recv_codecs_.begin(); 27180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != recv_codecs_.end(); ++it) { 27190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst voe_codec; 27200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->FindWebRtcCodec(*it, &voe_codec)) { 27210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.pltype = it->id; 27220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC 27230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->codec()->GetRecPayloadType( 27240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_channel(), voe_codec) != -1) { 27250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->codec()->SetRecPayloadType( 27260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel, voe_codec) == -1) { 27270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); 27280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 27290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 27340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 27357162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (InConferenceMode()) { 27367162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // To be in par with the video, voe_channel() is not used for receiving in 27377162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // a conference call. 27387162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (receive_channels_.empty() && default_receive_ssrc_ == 0 && playout_) { 27397162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // This is the first stream in a multi user meeting. We can now 27407162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // disable playback of the default stream. This since the default 27417162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // stream will probably have received some initial packets before 27427162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // the new stream was added. This will mean that the CN state from 27437162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // the default channel will be mixed in with the other streams 27447162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // throughout the whole meeting, which might be disturbing. 27457162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_INFO) << "Disabling playback on the default voice channel"; 27467162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org SetPlayout(voe_channel(), false); 27477162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 27480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2749952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org SetNack(channel, nack_enabled_); 27500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 27512ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org // Set RTP header extension for the new channel. 27522ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { 27532ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org return false; 27542ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org } 27552ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org 27565462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org // Set up channel to be able to forward incoming packets to video engine BWE. 27575462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (!SetupSharedBweOnChannel(channel)) { 27585462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 27595462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 27605462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org 27610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SetPlayout(channel, playout_); 27620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 27630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 27640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { 27652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&receive_channels_cs_); 27667162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org ChannelMap::iterator it = receive_channels_.find(ssrc); 2767f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (it == receive_channels_.end()) { 2768f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc 2769f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org << " which doesn't exist."; 27707162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return false; 2771f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 27720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2773b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this 2774b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // will disconnect the audio renderer with the receive channel. 2775b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // Cache the channel before the deletion. 2776b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org const int channel = it->second->channel(); 2777b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org delete it->second; 2778b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org receive_channels_.erase(it); 2779b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org 27807162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (ssrc == default_receive_ssrc_) { 2781b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ASSERT(IsDefaultChannel(channel)); 27827162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Recycle the default channel is for recv stream. 27837162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (playout_) 27847162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org SetPlayout(voe_channel(), false); 27857162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 27867162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org default_receive_ssrc_ = 0; 27877162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return true; 27887162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 27897162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 27907162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_INFO) << "Removing audio stream " << ssrc 2791b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org << " with VoiceEngine channel #" << channel << "."; 2792b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (!DeleteChannel(channel)) 27937162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return false; 27947162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 27957162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org bool enable_default_channel_playout = false; 27967162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (receive_channels_.empty()) { 27977162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // The last stream was removed. We can now enable the default 27987162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // channel for new channels to be played out immediately without 27997162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // waiting for AddStream messages. 28007162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // We do this for both conference mode and non-conference mode. 28017162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // TODO(oja): Does the default channel still have it's CN state? 28027162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org enable_default_channel_playout = true; 28037162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 28047162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (!InConferenceMode() && receive_channels_.size() == 1 && 28057162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org default_receive_ssrc_ != 0) { 28067162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Only the default channel is active, enable the playout on default 28077162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // channel. 28087162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org enable_default_channel_playout = true; 28097162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 28107162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (enable_default_channel_playout && playout_) { 28117162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org LOG(LS_INFO) << "Enabling playback on the default voice channel"; 28127162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org SetPlayout(voe_channel(), true); 28137162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 28147162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 28157162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return true; 28167162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org} 28177162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 28187162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, 28197162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org AudioRenderer* renderer) { 28207162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org ChannelMap::iterator it = receive_channels_.find(ssrc); 28217162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (it == receive_channels_.end()) { 28227162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (renderer) { 28237162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Return an error if trying to set a valid renderer with an invalid ssrc. 2824f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; 28250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 28260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 28270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 28287162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // The channel likely has gone away, do nothing. 28297162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org return true; 28307162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 28317162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 2832b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (renderer) 2833b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org it->second->Start(renderer); 2834b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org else 2835b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org it->second->Stop(); 28367162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 28370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 28380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 28390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 28407162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetLocalRenderer(uint32 ssrc, 28417162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org AudioRenderer* renderer) { 2842f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChannelMap::iterator it = send_channels_.find(ssrc); 2843f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (it == send_channels_.end()) { 2844f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (renderer) { 2845f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Return an error if trying to set a valid renderer with an invalid ssrc. 2846f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_ERROR) << "SetLocalRenderer failed with ssrc "<< ssrc; 2847f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return false; 2848f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 28497162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 2850f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // The channel likely has gone away, do nothing. 2851f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return true; 28527162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org } 28530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2854b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (renderer) 2855b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org it->second->Start(renderer); 2856b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org else 2857b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org it->second->Stop(); 28587162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org 28590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 28600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 28610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 28620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::GetActiveStreams( 28630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AudioInfo::StreamList* actives) { 28647162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // In conference mode, the default channel should not be in 28657162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // |receive_channels_|. 28660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org actives->clear(); 28677162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::iterator it = receive_channels_.begin(); 28687162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end(); ++it) { 2869b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int level = GetOutputLevel(it->second->channel()); 28700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (level > 0) { 28710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org actives->push_back(std::make_pair(it->first, level)); 28720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 28730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 28740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 28750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 28760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 28770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceMediaChannel::GetOutputLevel() { 28780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // return the highest output level of all streams 28790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int highest = GetOutputLevel(voe_channel()); 28807162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::iterator it = receive_channels_.begin(); 28817162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end(); ++it) { 2882b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org int level = GetOutputLevel(it->second->channel()); 28832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org highest = rtc::_max(level, highest); 28840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 28850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return highest; 28860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 28870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 28880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { 28890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int ret; 28900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { 28910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // In case of error, log the info and continue 28920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR0(TimeSinceLastTyping); 28930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret = -1; 28940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 28950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ret *= 1000; // We return ms, webrtc returns seconds. 28960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 28970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 28980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 28990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceMediaChannel::SetTypingDetectionParameters(int time_window, 29010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int cost_per_typing, int reporting_threshold, int penalty_decay, 29020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int type_event_delay) { 29030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->processing()->SetTypingDetectionParameters( 29040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org time_window, cost_per_typing, 29050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org reporting_threshold, penalty_decay, type_event_delay) == -1) { 29060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // In case of error, log the info and continue 29070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR5(SetTypingDetectionParameters, time_window, 29080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org cost_per_typing, reporting_threshold, penalty_decay, 29090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org type_event_delay); 29100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 29120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetOutputScaling( 29140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, double left, double right) { 29152a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&receive_channels_cs_); 29160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Collect the channels to scale the output volume. 29170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<int> channels; 29180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (0 == ssrc) { // Collect all channels, including the default one. 29197162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Default channel is not in receive_channels_ if it is not being used for 29207162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // playout. 29217162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (default_receive_ssrc_ == 0) 29227162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org channels.push_back(voe_channel()); 29237162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::const_iterator it = receive_channels_.begin(); 29247162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end(); ++it) { 2925b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org channels.push_back(it->second->channel()); 29260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { // Collect only the channel of the specified ssrc. 29280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel = GetReceiveChannelNum(ssrc); 29290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == channel) { 29300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; 29310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 29320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels.push_back(channel); 29340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Scale the output volume for the collected channels. We first normalize to 29370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // scale the volume and then set the left and right pan. 29382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org float scale = static_cast<float>(rtc::_max(left, right)); 29390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (scale > 0.0001f) { 29400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org left /= scale; 29410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org right /= scale; 29420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<int>::const_iterator it = channels.begin(); 29440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != channels.end(); ++it) { 29450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == engine()->voe()->volume()->SetChannelOutputVolumeScaling( 29460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *it, scale)) { 29470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(SetChannelOutputVolumeScaling, *it, scale); 29480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 29490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == engine()->voe()->volume()->SetOutputVolumePan( 29510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *it, static_cast<float>(left), static_cast<float>(right))) { 29520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR3(SetOutputVolumePan, *it, left, right); 29530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Do not return if fails. SetOutputVolumePan is not available for all 29540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // pltforms. 29550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "SetOutputScaling to left=" << left * scale 29570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " right=" << right * scale 29580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " for channel " << *it << " and ssrc " << ssrc; 29590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 29610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 29620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::GetOutputScaling( 29640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc, double* left, double* right) { 29650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!left || !right) return false; 29660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&receive_channels_cs_); 29680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Determine which channel based on ssrc. 29690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel = (0 == ssrc) ? voe_channel() : GetReceiveChannelNum(ssrc); 29700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel == -1) { 29710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; 29720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 29730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org float scaling; 29760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == engine()->voe()->volume()->GetChannelOutputVolumeScaling( 29770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel, scaling)) { 29780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(GetChannelOutputVolumeScaling, channel, scaling); 29790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 29800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org float left_pan; 29830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org float right_pan; 29840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (-1 == engine()->voe()->volume()->GetOutputVolumePan( 29850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel, left_pan, right_pan)) { 29860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR3(GetOutputVolumePan, channel, left_pan, right_pan); 29870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If GetOutputVolumePan fails, we use the default left and right pan. 29880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org left_pan = 1.0f; 29890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org right_pan = 1.0f; 29900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 29910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *left = scaling * left_pan; 29930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *right = scaling * right_pan; 29940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 29950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 29960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 29970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetRingbackTone(const char *buf, int len) { 29980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_tone_.reset(new WebRtcSoundclipStream(buf, len)); 29990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 30000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 30010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::PlayRingbackTone(uint32 ssrc, 30030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool play, bool loop) { 30040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ringback_tone_) { 30050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The voe file api is not available in chrome. 30090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!engine()->voe()->file()) { 30100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Determine which VoiceEngine channel to play on. 30140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int channel = (ssrc == 0) ? voe_channel() : GetReceiveChannelNum(ssrc); 30150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel == -1) { 30160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Make sure the ringtone is cued properly, and play it out. 30200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (play) { 30210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_tone_->set_loop(loop); 30220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_tone_->Rewind(); 30230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->file()->StartPlayingFileLocally(channel, 30240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_tone_.get()) == -1) { 30250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(StartPlayingFileLocally, channel, ringback_tone_.get()); 30260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Unable to start ringback tone"; 30270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_channels_.insert(channel); 30300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Started ringback on channel " << channel; 30310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 30320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->file()->IsPlayingFileLocally(channel) == 1 && 30330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->file()->StopPlayingFileLocally(channel) == -1) { 30340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StopPlayingFileLocally, channel); 30350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Stopped ringback on channel " << channel; 30380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_channels_.erase(channel); 30390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 30420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 30430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::CanInsertDtmf() { 30450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return dtmf_allowed_; 30460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 30470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::InsertDtmf(uint32 ssrc, int event, 30490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int duration, int flags) { 30500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!dtmf_allowed_) { 30510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send the event. 30550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (flags & cricket::DF_SEND) { 3056952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org int channel = -1; 3057952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (ssrc == 0) { 3058952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org bool default_channel_is_inuse = false; 3059952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org for (ChannelMap::const_iterator iter = send_channels_.begin(); 3060952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org iter != send_channels_.end(); ++iter) { 3061b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (IsDefaultChannel(iter->second->channel())) { 3062952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org default_channel_is_inuse = true; 3063952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org break; 3064952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 3065952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 3066952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org if (default_channel_is_inuse) { 3067952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org channel = voe_channel(); 3068952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } else if (!send_channels_.empty()) { 3069b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org channel = send_channels_.begin()->second->channel(); 3070952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 3071952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } else { 3072952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org channel = GetSendChannelNum(ssrc); 3073952740e2dafeb2599d21778eb2e1b8f1c8f2bb07wu@webrtc.org } 3074f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (channel == -1) { 30750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " 30760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ssrc << " is not in use."; 30770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send DTMF using out-of-band DTMF. ("true", as 3rd arg) 3080f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->dtmf()->SendTelephoneEvent( 3081f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel, event, true, duration) == -1) { 3082f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR4(SendTelephoneEvent, channel, event, true, duration); 30830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Play the event. 30880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (flags & cricket::DF_PLAY) { 30890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Play DTMF tone locally. 30900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->dtmf()->PlayDtmfTone(event, duration) == -1) { 30910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(PlayDtmfTone, event, duration); 30920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 30930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 30950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 30960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 30970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 30980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3099f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.orgvoid WebRtcVoiceMediaChannel::OnPacketReceived( 31002a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer* packet, const rtc::PacketTime& packet_time) { 31010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Pick which channel to send this packet to. If this packet doesn't match 31020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // any multiplexed streams, just send it to the default channel. Otherwise, 31030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // send it to the specific decoder instance for that stream. 31040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int which_channel = GetReceiveChannelNum( 31050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ParseSsrc(packet->data(), packet->length(), false)); 31060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (which_channel == -1) { 31070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org which_channel = voe_channel(); 31080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 31090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 31100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Stop any ringback that might be playing on the channel. 31110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // It's possible the ringback has already stopped, ih which case we'll just 31120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // use the opportunity to remove the channel from ringback_channels_. 31130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->file()) { 31140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::set<int>::iterator it = ringback_channels_.find(which_channel); 31150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it != ringback_channels_.end()) { 31160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->file()->IsPlayingFileLocally( 31170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org which_channel) == 1) { 31180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->file()->StopPlayingFileLocally(which_channel); 31190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Stopped ringback on channel " << which_channel 31200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " due to incoming media"; 31210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 31220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ringback_channels_.erase(which_channel); 31230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 31240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 31250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 31260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Pass it off to the decoder. 31271a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org engine()->voe()->network()->ReceivedRTPPacket( 31281a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org which_channel, 31291a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org packet->data(), 31305462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org static_cast<unsigned int>(packet->length()), 31315462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org webrtc::PacketTime(packet_time.timestamp, packet_time.not_before)); 31320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 31330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3134f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.orgvoid WebRtcVoiceMediaChannel::OnRtcpReceived( 31352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Buffer* packet, const rtc::PacketTime& packet_time) { 3136f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Sending channels need all RTCP packets with feedback information. 3137f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Even sender reports can contain attached report blocks. 3138f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Receiving channels need sender reports in order to create 3139f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // correct receiver reports. 3140f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int type = 0; 3141f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (!GetRtcpType(packet->data(), packet->length(), &type)) { 3142f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; 3143f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return; 3144f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3145f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3146f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // If it is a sender report, find the channel that is listening. 3147f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org bool has_sent_to_default_channel = false; 3148f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (type == kRtcpTypeSR) { 3149f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int which_channel = GetReceiveChannelNum( 3150f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ParseSsrc(packet->data(), packet->length(), true)); 3151f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (which_channel != -1) { 3152f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->voe()->network()->ReceivedRTCPPacket( 3153f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org which_channel, 3154f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org packet->data(), 3155f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org static_cast<unsigned int>(packet->length())); 3156f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3157f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (IsDefaultChannel(which_channel)) 3158f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org has_sent_to_default_channel = true; 3159f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3160f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3161f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3162f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // SR may continue RR and any RR entry may correspond to any one of the send 3163f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // channels. So all RTCP packets must be forwarded all send channels. VoE 3164f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // will filter out RR internally. 3165f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::iterator iter = send_channels_.begin(); 3166f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org iter != send_channels_.end(); ++iter) { 3167f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Make sure not sending the same packet to default channel more than once. 3168b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (IsDefaultChannel(iter->second->channel()) && 3169b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org has_sent_to_default_channel) 3170f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org continue; 31710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3172f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->voe()->network()->ReceivedRTCPPacket( 3173b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org iter->second->channel(), 3174f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org packet->data(), 3175f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org static_cast<unsigned int>(packet->length())); 3176f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 31770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 31780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 31790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { 3180f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); 3181f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (channel == -1) { 31820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; 31830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 31840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3185f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { 3186f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR2(SetInputMute, channel, muted); 31870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 31880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 31897663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org // We set the AGC to mute state only when all the channels are muted. 31907663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org // This implementation is not ideal, instead we should signal the AGC when 31917663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org // the mic channel is muted/unmuted. We can't do it today because there 31927663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org // is no good way to know which stream is mapping to the mic channel. 31937663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org bool all_muted = muted; 31947663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org for (ChannelMap::const_iterator iter = send_channels_.begin(); 31957663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org iter != send_channels_.end() && all_muted; ++iter) { 31967663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org if (engine()->voe()->volume()->GetInputMute(iter->second->channel(), 31977663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org all_muted)) { 31987663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org LOG_RTCERR1(GetInputMute, iter->second->channel()); 31997663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org return false; 32007663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org } 32017663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org } 32027663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org 32037663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); 32047663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org if (ap) 32057663c27fdfb3df16d08afced5d8b08026e91c05dbuildbot@webrtc.org ap->set_output_will_be_muted(all_muted); 32060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 32070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 32080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3209f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool WebRtcVoiceMediaChannel::SetStartSendBandwidth(int bps) { 3210f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org // TODO(andresp): Add support for setting an independent start bandwidth when 3211f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org // bandwidth estimation is enabled for voice engine. 3212f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org return false; 3213f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org} 32140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3215f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { 3216f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org LOG(LS_INFO) << "WebRtcVoiceMediaChanne::SetSendBandwidth."; 3217cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org 3218f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org return SetSendBandwidthInternal(bps); 3219cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org} 3220cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org 3221f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool WebRtcVoiceMediaChannel::SetSendBandwidthInternal(int bps) { 3222f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBandwidthInternal."; 3223f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org 3224f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org send_bw_setting_ = true; 3225f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org send_bw_bps_ = bps; 3226cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org 32270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!send_codec_) { 3228cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org LOG(LS_INFO) << "The send codec has not been set up yet. " 3229cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org << "The send bandwidth setting will be applied later."; 3230cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org return true; 32310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Bandwidth is auto by default. 3234f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by 3235f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org // SetMaxSendBandwith(0), the second call removes the previous limit. 3236f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org if (bps <= 0) 32370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 32380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst codec = *send_codec_; 32400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool is_multi_rate = IsCodecMultiRate(codec); 32410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (is_multi_rate) { 32430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If codec is multi-rate then just set the bitrate. 32440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org codec.rate = bps; 32450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!SetSendCodec(codec)) { 32460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Failed to set codec " << codec.plname 32470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " to bitrate " << bps << " bps."; 32480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 32490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 32510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 32520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If codec is not multi-rate and |bps| is less than the fixed bitrate 32530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // then fail. If codec is not multi-rate and |bps| exceeds or equal the 32540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // fixed bitrate then ignore. 32550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (bps < codec.rate) { 32560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Failed to set codec " << codec.plname 32570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " to bitrate " << bps << " bps" 32580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ", requires at least " << codec.rate << " bps."; 32590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 32600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 32620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 32640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { 32660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool echo_metrics_on = false; 32670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // These can take on valid negative values, so use the lowest possible level 32680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // as default rather than -1. 3269f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int echo_return_loss = -100; 3270f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int echo_return_loss_enhancement = -100; 32710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // These can also be negative, but in practice -1 is only used to signal 32720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // insufficient data, since the resolution is limited to multiples of 4 ms. 3273f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int echo_delay_median_ms = -1; 3274f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org int echo_delay_std_ms = -1; 3275f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->processing()->GetEcMetricsStatus( 3276f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org echo_metrics_on) != -1 && echo_metrics_on) { 32770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(ajm): we may want to use VoECallReport::GetEchoMetricsSummary 32780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // here, but it appears to be unsuitable currently. Revisit after this is 32790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // investigated: http://b/issue?id=5666755 32800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int erl, erle, rerl, anlp; 3281f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->processing()->GetEchoMetrics( 3282f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org erl, erle, rerl, anlp) != -1) { 3283f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org echo_return_loss = erl; 3284f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org echo_return_loss_enhancement = erle; 32850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 32870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int median, std; 32880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->processing()->GetEcDelayMetrics(median, std) != -1) { 3289f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org echo_delay_median_ms = median; 3290f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org echo_delay_std_ms = std; 32910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 32930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3294f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org webrtc::CallStatistics cs; 3295f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org unsigned int ssrc; 3296f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org webrtc::CodecInst codec; 3297f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org unsigned int level; 3298f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3299f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::const_iterator channel_iter = send_channels_.begin(); 3300f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel_iter != send_channels_.end(); ++channel_iter) { 3301b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org const int channel = channel_iter->second->channel(); 3302f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3303f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Fill in the sender info, based on what we know, and what the 3304f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // remote side told us it got from its RTCP report. 3305f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org VoiceSenderInfo sinfo; 3306f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3307f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->rtp()->GetRTCPStatistics(channel, cs) == -1 || 3308f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->voe()->rtp()->GetLocalSSRC(channel, ssrc) == -1) { 3309f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org continue; 3310f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3311f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 331297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org sinfo.add_ssrc(ssrc); 3313f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.codec_name = send_codec_.get() ? send_codec_->plname : ""; 3314f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.bytes_sent = cs.bytesSent; 3315f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.packets_sent = cs.packetsSent; 3316f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // RTT isn't known until a RTCP report is received. Until then, VoiceEngine 3317f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // returns 0 to indicate an error value. 3318f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.rtt_ms = (cs.rttMs > 0) ? cs.rttMs : -1; 3319f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3320f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Get data from the last remote RTCP report. Use default values if no data 3321f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // available. 3322f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.fraction_lost = -1.0; 3323f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.jitter_ms = -1; 3324f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.packets_lost = -1; 3325f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.ext_seqnum = -1; 3326f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org std::vector<webrtc::ReportBlock> receive_blocks; 3327f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->rtp()->GetRemoteRTCPReportBlocks( 3328f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel, &receive_blocks) != -1 && 3329f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org engine()->voe()->codec()->GetSendCodec(channel, codec) != -1) { 3330f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org std::vector<webrtc::ReportBlock>::iterator iter; 3331f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (iter = receive_blocks.begin(); iter != receive_blocks.end(); 3332f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ++iter) { 3333f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Lookup report for send ssrc only. 333497fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org if (iter->source_SSRC == sinfo.ssrc()) { 3335f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Convert Q8 to floating point. 3336f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.fraction_lost = static_cast<float>(iter->fraction_lost) / 256; 3337f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Convert samples to milliseconds. 3338f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (codec.plfreq / 1000 > 0) { 3339f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.jitter_ms = iter->interarrival_jitter / (codec.plfreq / 1000); 3340f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3341f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.packets_lost = iter->cumulative_num_packets_lost; 3342f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.ext_seqnum = iter->extended_highest_sequence_number; 3343f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org break; 3344f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3345f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3346f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3347f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3348f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Local speech level. 3349f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.audio_level = (engine()->voe()->volume()-> 3350f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org GetSpeechInputLevelFullRange(level) != -1) ? level : -1; 3351f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3352f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // TODO(xians): We are injecting the same APM logging to all the send 3353f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // channels here because there is no good way to know which send channel 3354f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // is using the APM. The correct fix is to allow the send channels to have 3355f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // their own APM so that we can feed the correct APM logging to different 3356f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // send channels. See issue crbug/264611 . 3357f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.echo_return_loss = echo_return_loss; 3358f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; 3359f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.echo_delay_median_ms = echo_delay_median_ms; 3360f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org sinfo.echo_delay_std_ms = echo_delay_std_ms; 33615528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org // TODO(ajm): Re-enable this metric once we have a reliable implementation. 33625528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org sinfo.aec_quality_min = -1; 33634ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org sinfo.typing_noise_detected = typing_noise_detected_; 3364f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3365f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org info->senders.push_back(sinfo); 3366f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 33670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 33687162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // Build the list of receivers, one for each receiving channel, or 1 in 33697162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org // a 1:1 call. 33700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<int> channels; 33717162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::const_iterator it = receive_channels_.begin(); 33727162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end(); ++it) { 3373b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org channels.push_back(it->second->channel()); 33740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 33750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channels.empty()) { 33760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels.push_back(voe_channel()); 33770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 33780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 33790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Get the SSRC and stats for each receiver, based on our own calculations. 33800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<int>::const_iterator it = channels.begin(); 33810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != channels.end(); ++it) { 33820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org memset(&cs, 0, sizeof(cs)); 33830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->rtp()->GetRemoteSSRC(*it, ssrc) != -1 && 33840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->rtp()->GetRTCPStatistics(*it, cs) != -1 && 33850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->codec()->GetRecCodec(*it, codec) != -1) { 33860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VoiceReceiverInfo rinfo; 338797fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org rinfo.add_ssrc(ssrc); 33880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.bytes_rcvd = cs.bytesReceived; 33890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.packets_rcvd = cs.packetsReceived; 33900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The next four fields are from the most recently sent RTCP report. 33910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Convert Q8 to floating point. 33920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.fraction_lost = static_cast<float>(cs.fractionLost) / (1 << 8); 33930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.packets_lost = cs.cumulativeLost; 33940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.ext_seqnum = cs.extendedMax; 3395842c369caaf7ab0115e101686ee5640a289da0e8buildbot@webrtc.org#ifdef USE_WEBRTC_DEV_BRANCH 3396842c369caaf7ab0115e101686ee5640a289da0e8buildbot@webrtc.org rinfo.capture_start_ntp_time_ms = cs.capture_start_ntp_time_ms_; 3397842c369caaf7ab0115e101686ee5640a289da0e8buildbot@webrtc.org#endif 3398ec0b1b83d70e08f3bd47940d33ad69cb8bb0878fbuildbot@webrtc.org if (codec.pltype != -1) { 3399ec0b1b83d70e08f3bd47940d33ad69cb8bb0878fbuildbot@webrtc.org rinfo.codec_name = codec.plname; 3400ec0b1b83d70e08f3bd47940d33ad69cb8bb0878fbuildbot@webrtc.org } 34010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Convert samples to milliseconds. 34020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (codec.plfreq / 1000 > 0) { 34030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.jitter_ms = cs.jitterSamples / (codec.plfreq / 1000); 34040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Get jitter buffer and total delay (alg + jitter + playout) stats. 34070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::NetworkStatistics ns; 34080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->neteq() && 34090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->neteq()->GetNetworkStatistics( 34100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *it, ns) != -1) { 34110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.jitter_buffer_ms = ns.currentBufferSize; 34120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.jitter_buffer_preferred_ms = ns.preferredBufferSize; 34130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.expand_rate = 34141a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org static_cast<float>(ns.currentExpandRate) / (1 << 14); 34150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 341654caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org 341754caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org webrtc::AudioDecodingCallStats ds; 341854caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org if (engine()->voe()->neteq() && 341954caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org engine()->voe()->neteq()->GetDecodingCallStatistics( 342054caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org *it, &ds) != -1) { 342154caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_calls_to_silence_generator = 342254caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org ds.calls_to_silence_generator; 342354caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_calls_to_neteq = ds.calls_to_neteq; 342454caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_normal = ds.decoded_normal; 342554caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_plc = ds.decoded_plc; 342654caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_cng = ds.decoded_cng; 342754caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org rinfo.decoding_plc_cng = ds.decoded_plc_cng; 342854caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org } 342954caffdda86e16e40218943b755a502c23b0940dhenrike@webrtc.org 34300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->sync()) { 343119da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org int jitter_buffer_delay_ms = 0; 34320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int playout_buffer_delay_ms = 0; 34330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->sync()->GetDelayEstimate( 343419da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org *it, &jitter_buffer_delay_ms, &playout_buffer_delay_ms); 343519da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org rinfo.delay_estimate_ms = jitter_buffer_delay_ms + 343619da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org playout_buffer_delay_ms; 34370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Get speech level. 34400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org rinfo.audio_level = (engine()->voe()->volume()-> 34410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org GetSpeechOutputLevelFullRange(*it, level) != -1) ? level : -1; 34420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org info->receivers.push_back(rinfo); 34430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 34470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 34480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceMediaChannel::GetLastMediaError( 34500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32* ssrc, VoiceMediaChannel::Error* error) { 34510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(ssrc != NULL); 34520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(error != NULL); 34530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org FindSsrc(voe_channel(), ssrc); 34540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = WebRtcErrorToChannelError(GetLastEngineError()); 34550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 34560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { 34582a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope lock(&receive_channels_cs_); 34590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(ssrc != NULL); 3460f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (channel_num == -1 && send_ != SEND_NOTHING) { 34610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sometimes the VoiceEngine core will throw error with channel_num = -1. 34620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This means the error is not limited to a specific channel. Signal the 34630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // message using ssrc=0. If the current channel is sending, use this 34640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // channel for sending the message. 34650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *ssrc = 0; 34660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 34670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3468f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // Check whether this is a sending channel. 3469f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org for (ChannelMap::const_iterator it = send_channels_.begin(); 3470f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org it != send_channels_.end(); ++it) { 3471b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (it->second->channel() == channel_num) { 3472f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org // This is a sending channel. 3473f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org uint32 local_ssrc = 0; 3474f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (engine()->voe()->rtp()->GetLocalSSRC( 3475f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org channel_num, local_ssrc) != -1) { 3476f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org *ssrc = local_ssrc; 3477f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3478f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return true; 3479f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3480f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org } 3481f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 34820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Check whether this is a receiving channel. 34837162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org for (ChannelMap::const_iterator it = receive_channels_.begin(); 34847162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org it != receive_channels_.end(); ++it) { 3485b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (it->second->channel() == channel_num) { 34860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *ssrc = it->first; 34870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 34880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 34910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 34920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 34930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 34940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) { 34954ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org if (error == VE_TYPING_NOISE_WARNING) { 34964ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org typing_noise_detected_ = true; 34974ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org } else if (error == VE_TYPING_NOISE_OFF_WARNING) { 34984ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org typing_noise_detected_ = false; 34994ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org } 35000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalMediaError(ssrc, WebRtcErrorToChannelError(error)); 35010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 35020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { 35040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org unsigned int ulevel; 35050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int ret = 35060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); 35070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (ret == 0) ? static_cast<int>(ulevel) : -1; 35080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 35090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) { 35117162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org ChannelMap::iterator it = receive_channels_.find(ssrc); 35127162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org if (it != receive_channels_.end()) 3513b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org return it->second->channel(); 35140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; 35150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 35160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) { 3518f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org ChannelMap::iterator it = send_channels_.find(ssrc); 3519f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org if (it != send_channels_.end()) 3520b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org return it->second->channel(); 3521f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org 3522f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org return -1; 35230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 35240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35255462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.orgbool WebRtcVoiceMediaChannel::SetupSharedBandwidthEstimation( 35265462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org webrtc::VideoEngine* vie, int vie_channel) { 35275462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_ = vie; 35285462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_channel_ = vie_channel; 35295462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org 35305462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (!SetupSharedBweOnChannel(voe_channel())) { 35315462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 35325462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 35335462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org for (ChannelMap::iterator it = receive_channels_.begin(); 35345462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org it != receive_channels_.end(); ++it) { 35355462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (!SetupSharedBweOnChannel(it->second->channel())) { 35365462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 35375462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 35385462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 35395462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return true; 35405462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org} 35415462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org 35420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, 35430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { 35440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Get the RED encodings from the parameter with no name. This may 35450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // change based on what is discussed on the Jingle list. 35460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The encoding parameter is of the form "a/b"; we only support where 35470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // a == b. Verify this and parse out the value into red_pt. 35480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If the parameter value is absent (as it will be until we wire up the 35490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // signaling of this message), use the second codec specified (i.e. the 35500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // one after "red") as the encoding parameter. 35510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int red_pt = -1; 35520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string red_params; 35530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CodecParameterMap::const_iterator it = red_codec.params.find(""); 35540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it != red_codec.params.end()) { 35550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org red_params = it->second; 35560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<std::string> red_pts; 35572a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (rtc::split(red_params, '/', &red_pts) != 2 || 35580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org red_pts[0] != red_pts[1] || 35592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org !rtc::FromString(red_pts[0], &red_pt)) { 35600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "RED params " << red_params << " not supported."; 35610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 35620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (red_codec.params.empty()) { 35640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "RED params not present, using defaults"; 35650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (all_codecs.size() > 1) { 35660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org red_pt = all_codecs[1].id; 35670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Try to find red_pt in |codecs|. 35710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<AudioCodec>::const_iterator codec; 35720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (codec = all_codecs.begin(); codec != all_codecs.end(); ++codec) { 35730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (codec->id == red_pt) 35740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 35750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we find the right codec, that will be the codec we pass to 35780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // SetSendCodec, with the desired payload type. 35790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (codec != all_codecs.end() && 35800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->FindWebRtcCodec(*codec, send_codec)) { 35810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 35820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; 35830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 35840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 35870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 35880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 35890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { 35900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { 3591f99f1011aa4cd22bd86ba2e4f7d239ea1b766ec8wu@webrtc.org LOG_RTCERR2(SetRTCPStatus, channel, 1); 35920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 35930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 35940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what 35950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // what we want to do with them. 35960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // engine()->voe().EnableVQMon(voe_channel(), true); 35970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // engine()->voe().EnableRTCP_XR(voe_channel(), true); 35980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 35990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 36000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::ResetRecvCodecs(int channel) { 36020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int ncodecs = engine()->voe()->codec()->NumOfCodecs(); 36030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (int i = 0; i < ncodecs; ++i) { 36040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org webrtc::CodecInst voe_codec; 36050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { 36060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org voe_codec.pltype = -1; 36070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->codec()->SetRecPayloadType( 36080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel, voe_codec) == -1) { 36090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); 36100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 36110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 36150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 36160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { 36180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (playout) { 36190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Starting playout for channel #" << channel; 36200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (engine()->voe()->base()->StartPlayout(channel) == -1) { 36210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_RTCERR1(StartPlayout, channel); 36220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 36230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 36250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Stopping playout for channel #" << channel; 36260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org engine()->voe()->base()->StopPlayout(channel); 36270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 36290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 36300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orguint32 WebRtcVoiceMediaChannel::ParseSsrc(const void* data, size_t len, 36320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool rtcp) { 36330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t ssrc_pos = (!rtcp) ? 8 : 4; 36340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 ssrc = 0; 36350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (len >= (ssrc_pos + sizeof(ssrc))) { 36362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org ssrc = rtc::GetBE32(static_cast<const char*>(data) + ssrc_pos); 36370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ssrc; 36390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 36400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Convert VoiceEngine error code into VoiceMediaChannel::Error enum. 36420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgVoiceMediaChannel::Error 36430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { 36440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (err_code) { 36450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case 0: 36460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_NONE; 36470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_CANNOT_START_RECORDING: 36480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_MIC_VOL_ERROR: 36490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_GET_MIC_VOL_ERROR: 36500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_CANNOT_ACCESS_MIC_VOL: 36510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_REC_DEVICE_OPEN_FAILED; 36520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_SATURATION_WARNING: 36530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_REC_DEVICE_SATURATION; 36540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_REC_DEVICE_REMOVED: 36550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_REC_DEVICE_REMOVED; 36560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_RUNTIME_REC_WARNING: 36570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_RUNTIME_REC_ERROR: 36580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_REC_RUNTIME_ERROR; 36590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_CANNOT_START_PLAYOUT: 36600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_SPEAKER_VOL_ERROR: 36610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_GET_SPEAKER_VOL_ERROR: 36620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_CANNOT_ACCESS_SPEAKER_VOL: 36630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_PLAY_DEVICE_OPEN_FAILED; 36640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_RUNTIME_PLAY_WARNING: 36650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_RUNTIME_PLAY_ERROR: 36660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_PLAY_RUNTIME_ERROR; 36670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case VE_TYPING_NOISE_WARNING: 36680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ERROR_REC_TYPING_NOISE_DETECTED; 36690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 36700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return VoiceMediaChannel::ERROR_OTHER; 36710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 36720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 36730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 36743ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.orgbool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter, 36753ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org int channel_id, const RtpHeaderExtension* extension) { 36763ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org bool enable = false; 36772ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org int id = 0; 36782ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org std::string uri; 36793ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org if (extension) { 36803ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org enable = true; 36813ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org id = extension->id; 36822ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org uri = extension->uri; 36833ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 36843ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org if ((engine()->voe()->rtp()->*setter)(channel_id, enable, id) != 0) { 36852ccf00b08449e81bc72367010d65f4210f7fb60ebuildbot@webrtc.org LOG_RTCERR4(*setter, uri, channel_id, enable, id); 36863ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return false; 36873ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org } 36883ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org return true; 36893ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org} 36903ca77cb43bc675f562521d4c90e8156a6e088cbchenrike@webrtc.org 36915462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.orgbool WebRtcVoiceMediaChannel::SetupSharedBweOnChannel(int voe_channel) { 36925462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org webrtc::ViENetwork* vie_network = NULL; 36935462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org int vie_channel = -1; 36945462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (options_.combined_audio_video_bwe.GetWithDefaultIfUnset(false) && 36955462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org shared_bwe_vie_ != NULL && shared_bwe_vie_channel_ != -1) { 36965462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org vie_network = webrtc::ViENetwork::GetInterface(shared_bwe_vie_); 36975462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org vie_channel = shared_bwe_vie_channel_; 36985462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 36995462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (engine()->voe()->rtp()->SetVideoEngineBWETarget(voe_channel, vie_network, 37005462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org vie_channel) == -1) { 37015462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org LOG_RTCERR3(SetVideoEngineBWETarget, voe_channel, vie_network, vie_channel); 37025462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org if (vie_network != NULL) { 37035462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org // Don't fail if we're tearing down. 37045462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return false; 37055462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 37065462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org } 37075462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org return true; 37085462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org} 37095462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org 37100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcSoundclipStream::Read(void *buf, int len) { 37110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t res = 0; 37120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org mem_.Read(buf, len, &res, NULL); 37131a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org return static_cast<int>(res); 37140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 37150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 37160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint WebRtcSoundclipStream::Rewind() { 37170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org mem_.Rewind(); 37180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Return -1 to keep VoiceEngine from looping. 37190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (loop_) ? 0 : -1; 37200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 37210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 37220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 37230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 37240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#endif // HAVE_WEBRTC_VOICE 3725