channel.cc revision ac547a653862744d0aae560713f8418ad2852085
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/* 22919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Use of this source code is governed by a BSD-style license 5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that can be found in the LICENSE file in the root of the source 6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * tree. An additional intellectual property rights grant can be found 7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * in the file PATENTS. All contributing project authors may 8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * be found in the AUTHORS file in the root of the source tree. 9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */ 10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 116388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/channel.h" 126388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 1364dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin#include <algorithm> 1464dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin 15ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen#include "webrtc/base/checks.h" 164591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include "webrtc/base/format_macros.h" 1794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org#include "webrtc/base/timeutils.h" 18e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org#include "webrtc/common.h" 1964dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin#include "webrtc/config.h" 206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_device/include/audio_device.h" 216388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_processing/include/audio_processing.h" 22d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 23822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" 24822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 25822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 26822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" 276388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/audio_frame_operations.h" 286388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/process_thread.h" 296388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 306388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_base.h" 336388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_external_media.h" 346388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_rtp_rtcp.h" 356388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/output_mixer.h" 366388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/statistics.h" 376388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 386388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/utility.h" 39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#if defined(_WIN32) 41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <Qos.h> 42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4450419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace webrtc { 4550419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace voe { 46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// Extend the default RTCP statistics struct with max_jitter, defined as the 4854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// maximum jitter value seen in an RTCP report block. 4954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.orgstruct ChannelStatistics : public RtcpStatistics { 5054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics() : rtcp(), max_jitter(0) {} 5154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 5254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics rtcp; 5354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org uint32_t max_jitter; 5454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org}; 5554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 5654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// Statistics callback, called at each generation of a new RTCP report block. 5754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.orgclass StatisticsProxy : public RtcpStatisticsCallback { 5854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org public: 5954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org StatisticsProxy(uint32_t ssrc) 6054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org : stats_lock_(CriticalSectionWrapper::CreateCriticalSection()), 6154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ssrc_(ssrc) {} 6254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org virtual ~StatisticsProxy() {} 6354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 6414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void StatisticsUpdated(const RtcpStatistics& statistics, 6514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org uint32_t ssrc) override { 6654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (ssrc != ssrc_) 6754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org return; 6854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 6954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org CriticalSectionScoped cs(stats_lock_.get()); 7054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_.rtcp = statistics; 7154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (statistics.jitter > stats_.max_jitter) { 7254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_.max_jitter = statistics.jitter; 7354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 7454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 7554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 7614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void CNameChanged(const char* cname, uint32_t ssrc) override {} 77ce4e9a356200170abcdd44ff2af95f87a6781b8epbos@webrtc.org 7854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics GetStats() { 7954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org CriticalSectionScoped cs(stats_lock_.get()); 8054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org return stats_; 8154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 8254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 8354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org private: 8454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // StatisticsUpdated calls are triggered from threads in the RTP module, 8554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // while GetStats calls can be triggered from the public voice engine API, 8654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // hence synchronization is needed. 8700b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<CriticalSectionWrapper> stats_lock_; 8854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org const uint32_t ssrc_; 8954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics stats_; 9054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org}; 9154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 920a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.orgclass VoERtcpObserver : public RtcpBandwidthObserver { 93c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org public: 940a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org explicit VoERtcpObserver(Channel* owner) : owner_(owner) {} 950a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org virtual ~VoERtcpObserver() {} 960a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 970a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org void OnReceivedEstimatedBitrate(uint32_t bitrate) override { 980a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Not used for Voice Engine. 990a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1000a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 10114665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks, 10214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int64_t rtt, 10314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int64_t now_ms) override { 1040a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // TODO(mflodman): Do we need to aggregate reports here or can we jut send 1050a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // what we get? I.e. do we ever get multiple reports bundled into one RTCP 1060a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // report for VoiceEngine? 1070a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (report_blocks.empty()) 1080a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org return; 1090a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1100a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int fraction_lost_aggregate = 0; 1110a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int total_number_of_packets = 0; 1120a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1130a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // If receiving multiple report blocks, calculate the weighted average based 1140a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // on the number of packets a report refers to. 1150a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org for (ReportBlockList::const_iterator block_it = report_blocks.begin(); 1160a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org block_it != report_blocks.end(); ++block_it) { 1170a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Find the previous extended high sequence number for this remote SSRC, 1180a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // to calculate the number of RTP packets this report refers to. Ignore if 1190a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // we haven't seen this SSRC before. 1200a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org std::map<uint32_t, uint32_t>::iterator seq_num_it = 1210a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org extended_max_sequence_number_.find(block_it->sourceSSRC); 1220a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int number_of_packets = 0; 1230a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (seq_num_it != extended_max_sequence_number_.end()) { 1240a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org number_of_packets = block_it->extendedHighSeqNum - seq_num_it->second; 1250a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1260a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org fraction_lost_aggregate += number_of_packets * block_it->fractionLost; 1270a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org total_number_of_packets += number_of_packets; 1280a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1290a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org extended_max_sequence_number_[block_it->sourceSSRC] = 1300a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org block_it->extendedHighSeqNum; 1310a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1320a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int weighted_fraction_lost = 0; 1330a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (total_number_of_packets > 0) { 1340a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org weighted_fraction_lost = (fraction_lost_aggregate + 1350a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org total_number_of_packets / 2) / total_number_of_packets; 1360a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1370a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org owner_->OnIncomingFractionLoss(weighted_fraction_lost); 138c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 139c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 140c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org private: 141c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org Channel* owner_; 1420a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Maps remote side ssrc to extended highest sequence number received. 1430a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org std::map<uint32_t, uint32_t> extended_max_sequence_number_; 144c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org}; 145c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 1466141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendData(FrameType frameType, 1486141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t payloadType, 1496141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t timeStamp, 1506141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t* payloadData, 1514591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payloadSize, 152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const RTPFragmentationHeader* fragmentation) 153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," 1564591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org " payloadSize=%" PRIuS ", fragmentation=0x%x)", 1574591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org frameType, payloadType, timeStamp, 1584591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org payloadSize, fragmentation); 159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_includeAudioLevelIndication) 161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store current audio level in the RTP/RTCP module. 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The level will be used in combination with voice-activity state 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (frameType) to add an RTP header extension 165382c0c209d323c1e6972d988a7b26f08fc2e8a6bandrew@webrtc.org _rtpRtcpModule->SetAudioLevel(rms_level_.RMS()); 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push data from ACM to RTP/RTCP-module to deliver audio frame for 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packetization. 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call will trigger Transport::SendPacket() from the RTP/RTCP module. 1712853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadType, 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeStamp, 174ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // Leaving the time when this frame was 175ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // received from the capture device as 176ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // undefined for voice for now. 177ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org -1, 178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadData, 179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fragmentation) == -1) 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData() failed to send data to RTP/RTCP module"); 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp = timeStamp; 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType = payloadType; 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1946141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 195e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.orgChannel::InFrameType(FrameType frame_type) 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 198e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.org "Channel::InFrameType(frame_type=%d)", frame_type); 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2009a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 201e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.org _sendFrameType = (frame_type == kAudioFrameSpeech); 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2056141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2069213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnRxVadDetected(int vadDecision) 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnRxVadDetected(vadDecision=%d)", vadDecision); 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2119a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 221ac547a653862744d0aae560713f8418ad2852085Peter BoströmChannel::SendPacket(const void *data, size_t len) 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 224ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len); 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 226fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 227fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() failed to send RTP packet due to" 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " invalid transport object"); 233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2366141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 2374591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bufferLength = len; 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 239ac547a653862744d0aae560713f8418ad2852085Peter Boström int n = _transportPtr->SendPacket(bufferToSendPtr, bufferLength); 240fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (n < 0) { 241fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org std::string transport_name = 242fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org _externalTransport ? "external transport" : "WebRtc sockets"; 243fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 244fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 245fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendPacket() RTP transmission using %s failed", 246fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org transport_name.c_str()); 247fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 249fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return n; 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 253ac547a653862744d0aae560713f8418ad2852085Peter BoströmChannel::SendRTCPPacket(const void *data, size_t len) 254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 256ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::SendRTCPPacket(len=%" PRIuS ")", len); 257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 258fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 259fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (_transportPtr == NULL) 260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 261fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 262fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 263fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendRTCPPacket() failed to send RTCP packet" 264fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org " due to invalid transport object"); 265fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 2694591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bufferLength = len; 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 271ac547a653862744d0aae560713f8418ad2852085Peter Boström int n = _transportPtr->SendRTCPPacket(bufferToSendPtr, bufferLength); 272fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (n < 0) { 273fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org std::string transport_name = 274fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org _externalTransport ? "external transport" : "WebRtc sockets"; 275fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 276fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 277fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendRTCPPacket() transmission using %s failed", 278fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org transport_name.c_str()); 279fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 281fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return n; 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 284ac547a653862744d0aae560713f8418ad2852085Peter Boströmvoid Channel::OnPlayTelephoneEvent(uint8_t event, 285ac547a653862744d0aae560713f8418ad2852085Peter Boström uint16_t lengthMs, 286ac547a653862744d0aae560713f8418ad2852085Peter Boström uint8_t volume) { 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 288ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u," 289ac547a653862744d0aae560713f8418ad2852085Peter Boström " volume=%u)", event, lengthMs, volume); 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playOutbandDtmfEvent || (event > 15)) 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ignore callback since feedback is disabled or event is not a 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dtmf tone event. 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(_outputMixerPtr != NULL); 299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playing out the Dtmf tone (if playout is enabled). 301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reduce length of tone with 80ms to the reduce risk of echo. 302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); 303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 306ac547a653862744d0aae560713f8418ad2852085Peter BoströmChannel::OnIncomingSSRCChanged(uint32_t ssrc) 307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 309ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::OnIncomingSSRCChanged(SSRC=%d)", ssrc); 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 311b295a3f5920e2706d42c960c5180c7cc6e1f435edwkang@webrtc.org // Update ssrc so that NTP for AV sync can be updated. 312b295a3f5920e2706d42c960c5180c7cc6e1f435edwkang@webrtc.org _rtpRtcpModule->SetRemoteSSRC(ssrc); 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 315ac547a653862744d0aae560713f8418ad2852085Peter Boströmvoid Channel::OnIncomingCSRCChanged(uint32_t CSRC, bool added) { 316ac547a653862744d0aae560713f8418ad2852085Peter Boström WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 317ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::OnIncomingCSRCChanged(CSRC=%d, added=%d)", CSRC, 318ac547a653862744d0aae560713f8418ad2852085Peter Boström added); 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 321ac547a653862744d0aae560713f8418ad2852085Peter Boströmint32_t Channel::OnInitializeDecoder( 3229213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int8_t payloadType, 323813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char payloadName[RTP_PAYLOAD_NAME_SIZE], 3249213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int frequency, 3259213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t channels, 326ac547a653862744d0aae560713f8418ad2852085Peter Boström uint32_t rate) { 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 328ac547a653862744d0aae560713f8418ad2852085Peter Boström "Channel::OnInitializeDecoder(payloadType=%d, " 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "payloadName=%s, frequency=%u, channels=%u, rate=%u)", 330ac547a653862744d0aae560713f8418ad2852085Peter Boström payloadType, payloadName, frequency, channels, rate); 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 332f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst receiveCodec = {0}; 333f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst dummyCodec = {0}; 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pltype = payloadType; 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.plfreq = frequency; 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.channels = channels; 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.rate = rate; 339f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 340ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 341eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels); 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pacsize = dummyCodec.pacsize; 343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register the new codec to the ACM 345eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(receiveCodec) == -1) 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 348ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org VoEId(_instanceId, _channelId), 349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder() invalid codec (" 350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "pt=%d, name=%s) received - 1", payloadType, payloadName); 351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3586141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 3596141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::OnReceivedPayloadData(const uint8_t* payloadData, 3604591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payloadSize, 361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtcRTPHeader* rtpHeader) 362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3644591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS "," 365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " payloadType=%u, audioChannel=%u)", 366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.payloadType, 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->type.Audio.channel); 369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 370944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing) 371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid inserting into NetEQ when we are not playing. Count the 373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packet as discarded. 374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "received packet is discarded since playing is not" 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " activated"); 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets++; 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push the incoming payload (parsed and ready for decoding) into the ACM 383eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->IncomingPacket(payloadData, 384eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org payloadSize, 385eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org *rtpHeader) != 0) 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData() unable to push data to the ACM"); 390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 393d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org // Update the packet delay. 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdatePacketDelay(rtpHeader->header.timestamp, 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.sequenceNumber); 396d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org 39716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t round_trip_time = 0; 398822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, 399822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org NULL, NULL, NULL); 400822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 401eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org std::vector<uint16_t> nack_list = audio_coding_->GetNackList( 402822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org round_trip_time); 403822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!nack_list.empty()) { 404822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // Can't use nack_list.data() since it's not supported by all 405822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // compilers. 406822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size())); 407d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org } 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4117bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::OnRecoveredPacket(const uint8_t* rtp_packet, 4124591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtp_packet_length) { 4137bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org RTPHeader header; 4147bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { 4157bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVoice, _channelId, 4167bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "IncomingPacket invalid RTP header"); 4177bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4187bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 4197bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org header.payload_type_frequency = 4207bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); 4217bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (header.payload_type_frequency < 0) 4227bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4237bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ReceivePacket(rtp_packet, rtp_packet_length, header, false); 4247bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 4257bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 4260f4b3731c34e796da92572380855dbc7321c8cfeminyuelint32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame) 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame(id=%d)", id); 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 431ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen if (event_log_) { 432ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen unsigned int ssrc; 433ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0); 434ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen event_log_->LogAudioPlayout(ssrc); 435ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen } 436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms raw PCM data from the ACM (mixer limits output frequency) 4370f4b3731c34e796da92572380855dbc7321c8cfeminyuel if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, 4380f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame) == -1) 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); 4437859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // In all likelihood, the audio in this frame is garbage. We return an 4447859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // error so that the audio mixer module doesn't add it to the mix. As 4457859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // a result, it won't be played out and the actions skipped here are 4467859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // irrelevant. 4477859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org return -1; 448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_RxVadDetection) 451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4520f4b3731c34e796da92572380855dbc7321c8cfeminyuel UpdateRxVadDetection(*audioFrame); 453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Convert module ID to internal VoE channel ID 4560f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->id_ = VoEChannelId(audioFrame->id_); 457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store speech type for dead-or-alive detection 4580f4b3731c34e796da92572380855dbc7321c8cfeminyuel _outputSpeechType = audioFrame->speech_type_; 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 460944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org ChannelState::State state = channel_state_.Get(); 461944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 462944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (state.rx_apm_is_enabled) { 4630f4b3731c34e796da92572380855dbc7321c8cfeminyuel int err = rx_audioproc_->ProcessStream(audioFrame); 46460730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org if (err) { 46560730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org LOG(LS_ERROR) << "ProcessStream() error: " << err; 46660730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org assert(false); 46760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org } 468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 47063420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float output_gain = 1.0f; 47163420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float left_pan = 1.0f; 47263420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float right_pan = 1.0f; 47363420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org { 47463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 47563420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org output_gain = _outputGain; 47663420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org left_pan = _panLeft; 47763420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org right_pan= _panRight; 47863420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org } 47963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Output volume scaling 48163420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org if (output_gain < 0.99f || output_gain > 1.01f) 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4830f4b3731c34e796da92572380855dbc7321c8cfeminyuel AudioFrameOperations::ScaleWithSat(output_gain, *audioFrame); 484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale left and/or right channel(s) if stereo and master balance is 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // active 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 48963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org if (left_pan != 1.0f || right_pan != 1.0f) 490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4910f4b3731c34e796da92572380855dbc7321c8cfeminyuel if (audioFrame->num_channels_ == 1) 492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Emulate stereo mode since panning is active. 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The mono signal is copied to both left and right channels here. 4950f4b3731c34e796da92572380855dbc7321c8cfeminyuel AudioFrameOperations::MonoToStereo(audioFrame); 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // For true stereo mode (when we are receiving a stereo signal), no 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // action is needed. 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Do the panning operation (the audio frame contains stereo at this 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stage) 5020f4b3731c34e796da92572380855dbc7321c8cfeminyuel AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame); 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Mix decoded PCM output with file if file mixing is enabled 506944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (state.output_file_playing) 507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5080f4b3731c34e796da92572380855dbc7321c8cfeminyuel MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_); 509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // External media 512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5149a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 5150f4b3731c34e796da92572380855dbc7321c8cfeminyuel const bool isStereo = (audioFrame->num_channels_ == 2); 516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr->Process( 519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kPlaybackPerChannel, 5210f4b3731c34e796da92572380855dbc7321c8cfeminyuel (int16_t*)audioFrame->data_, 5220f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->samples_per_channel_, 5230f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->sample_rate_hz_, 524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Record playout if enabled 529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5309a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording && _outputFileRecorderPtr) 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5340f4b3731c34e796da92572380855dbc7321c8cfeminyuel _outputFileRecorderPtr->RecordAudioToFile(*audioFrame); 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Measure audio level (0-9) 5390f4b3731c34e796da92572380855dbc7321c8cfeminyuel _outputAudioLevel.ComputeLevel(*audioFrame); 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5410f4b3731c34e796da92572380855dbc7321c8cfeminyuel if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) { 54294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // The first frame with a valid rtp timestamp. 5430f4b3731c34e796da92572380855dbc7321c8cfeminyuel capture_start_rtp_time_stamp_ = audioFrame->timestamp_; 54494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 54594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 54694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (capture_start_rtp_time_stamp_ >= 0) { 54794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // audioFrame.timestamp_ should be valid from now on. 54894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 54994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // Compute elapsed time. 55094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int64_t unwrap_timestamp = 5510f4b3731c34e796da92572380855dbc7321c8cfeminyuel rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_); 5520f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->elapsed_time_ms_ = 55394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org (unwrap_timestamp - capture_start_rtp_time_stamp_) / 55494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org (GetPlayoutFrequency() / 1000); 55594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 5568e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org { 557cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 5588e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // Compute ntp time. 5590f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->ntp_time_ms_ = ntp_estimator_.Estimate( 5600f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->timestamp_); 5618e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. 5620f4b3731c34e796da92572380855dbc7321c8cfeminyuel if (audioFrame->ntp_time_ms_ > 0) { 5638e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // Compute |capture_start_ntp_time_ms_| so that 5648e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| 5658e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org capture_start_ntp_time_ms_ = 5660f4b3731c34e796da92572380855dbc7321c8cfeminyuel audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_; 5678e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org } 568cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 569cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 570cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5746141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 5750f4b3731c34e796da92572380855dbc7321c8cfeminyuelChannel::NeededFrequency(int32_t id) const 576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::NeededFrequency(id=%d)", id); 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int highestNeeded = 0; 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Determine highest needed receive frequency 583eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org int32_t receiveFrequency = audio_coding_->ReceiveFrequency(); 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Return the bigger of playout and receive frequency in the ACM. 586eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->PlayoutFrequency() > receiveFrequency) 587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 588eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org highestNeeded = audio_coding_->PlayoutFrequency(); 589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = receiveFrequency; 593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Special case, if we're playing a file on the playout side 596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // we take that frequency into consideration as well 597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is not needed on sending side, since the codec will 598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // limit the spectrum anyway. 599944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6019a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 602944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (_outputFilePlayerPtr) 603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_outputFilePlayerPtr->Frequency()>highestNeeded) 605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded=_outputFilePlayerPtr->Frequency(); 607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(highestNeeded); 612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 614b04965ccf83c2bc6e2758abab9bea0c18551a54civocint32_t Channel::CreateChannel(Channel*& channel, 615b04965ccf83c2bc6e2758abab9bea0c18551a54civoc int32_t channelId, 616b04965ccf83c2bc6e2758abab9bea0c18551a54civoc uint32_t instanceId, 617b04965ccf83c2bc6e2758abab9bea0c18551a54civoc RtcEventLog* const event_log, 618b04965ccf83c2bc6e2758abab9bea0c18551a54civoc const Config& config) { 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), 620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel(channelId=%d, instanceId=%d)", 621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channelId, instanceId); 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 623b04965ccf83c2bc6e2758abab9bea0c18551a54civoc channel = new Channel(channelId, instanceId, event_log, config); 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (channel == NULL) 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(instanceId,channelId), 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel() unable to allocate memory for" 629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " channel"); 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6369213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayNotification(int32_t id, uint32_t durationMs) 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayNotification(id=%d, durationMs=%d)", 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6469213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordNotification(int32_t id, uint32_t durationMs) 647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordNotification(id=%d, durationMs=%d)", 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6569213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayFileEnded(int32_t id) 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded(id=%d)", id); 660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (id == _inputFilePlayerId) 662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 663944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(false); 664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => input file player module is" 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (id == _outputFilePlayerId) 670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 671944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => output file player module is" 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6809213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordFileEnded(int32_t id) 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded(id=%d)", id); 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(id == _outputFileRecorderId); 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6879a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded() => output file recorder module is" 693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6969213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::Channel(int32_t channelId, 697e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org uint32_t instanceId, 698b04965ccf83c2bc6e2758abab9bea0c18551a54civoc RtcEventLog* const event_log, 699b04965ccf83c2bc6e2758abab9bea0c18551a54civoc const Config& config) 700b04965ccf83c2bc6e2758abab9bea0c18551a54civoc : _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 70263420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org volume_settings_critsect_(*CriticalSectionWrapper::CreateCriticalSection()), 703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _instanceId(instanceId), 70422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _channelId(channelId), 705ae856f2c9fc358e5cd68d8a595136dcef017ed96Ivo Creusen event_log_(event_log), 706a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org rtp_header_parser_(RtpHeaderParser::Create()), 707822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_( 708dc80bae2a62a1bdbe0d342b3260a7e5b2cb958dfandresp@webrtc.org new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true))), 709b04965ccf83c2bc6e2758abab9bea0c18551a54civoc rtp_receive_statistics_( 710b04965ccf83c2bc6e2758abab9bea0c18551a54civoc ReceiveStatistics::Create(Clock::GetRealTimeClock())), 711b04965ccf83c2bc6e2758abab9bea0c18551a54civoc rtp_receiver_( 712ac547a653862744d0aae560713f8418ad2852085Peter Boström RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(), 713b04965ccf83c2bc6e2758abab9bea0c18551a54civoc this, 714b04965ccf83c2bc6e2758abab9bea0c18551a54civoc this, 715b04965ccf83c2bc6e2758abab9bea0c18551a54civoc this, 716b04965ccf83c2bc6e2758abab9bea0c18551a54civoc rtp_payload_registry_.get())), 717822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()), 718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel(), 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport(false), 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr(NULL), 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr(NULL), 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr(NULL), 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid conflict with other channels by adding 1024 - 1026, 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // won't use as much as 1024 channels. 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), 727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording(false), 72922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), 73022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), 73122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputExternalMedia(false), 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr(NULL), 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr(NULL), 734b04965ccf83c2bc6e2758abab9bea0c18551a54civoc _timeStamp(0), // This is just an offset, RTP module will add it's own 735b04965ccf83c2bc6e2758abab9bea0c18551a54civoc // random offset 73622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendTelephoneEventPayloadType(106), 7378e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org ntp_estimator_(Clock::GetRealTimeClock()), 738167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org jitter_buffer_playout_timestamp_(0), 7391de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtp_(0), 7401de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_(0), 74154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org playout_delay_ms_(0), 74222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _numberOfDiscardedPackets(0), 74309e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org send_sequence_number_(0), 744cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org ts_stats_lock_(CriticalSectionWrapper::CreateCriticalSection()), 74594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), 74694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org capture_start_rtp_time_stamp_(-1), 747cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org capture_start_ntp_time_ms_(-1), 74822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _engineStatisticsPtr(NULL), 7492919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _outputMixerPtr(NULL), 7502919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _transmitMixerPtr(NULL), 75122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _moduleProcessThreadPtr(NULL), 75222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _audioDeviceModulePtr(NULL), 75322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _voiceEngineObserverPtr(NULL), 75422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _callbackCritSectPtr(NULL), 75522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _transportPtr(NULL), 75622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxVadObserverPtr(NULL), 75722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _oldVadDecision(-1), 75822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendFrameType(0), 7591b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing(false), 76022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _mixFileWithMicrophone(false), 761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute(false), 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft(1.0f), 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight(1.0f), 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain(1.0f), 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent(false), 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent(false), 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp(0), 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType(0), 76922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _includeAudioLevelIndication(false), 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputSpeechType(AudioFrame::kNormalSpeech), 771743758816853df2040a21c5652b0d0e238b1512fdeadbeef video_sync_lock_(CriticalSectionWrapper::CreateCriticalSection()), 7721de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us(0), 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousTimestamp(0), 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recPacketDelayMs(20), 775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection(false), 776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled(false), 7777bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org _rxNsIsEnabled(false), 778c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org restored_packet_in_use_(false), 7790a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org rtcp_observer_(new VoERtcpObserver(this)), 7802013aeced2b7821a407f302802c4a16fd02728b1Minyue network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())), 7812013aeced2b7821a407f302802c4a16fd02728b1Minyue assoc_send_channel_lock_(CriticalSectionWrapper::CreateCriticalSection()), 782b04965ccf83c2bc6e2758abab9bea0c18551a54civoc associate_send_channel_(ChannelOwner(nullptr)) { 783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Channel() - ctor"); 78564dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin AudioCodingModule::Config acm_config; 78664dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin acm_config.id = VoEModuleId(instanceId, channelId); 78764dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin if (config.Get<NetEqCapacityConfig>().enabled) { 78864dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin // Clamping the buffer capacity at 20 packets. While going lower will 78964dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin // probably work, it makes little sense. 79064dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin acm_config.neteq_config.max_packets_in_buffer = 79164dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin std::max(20, config.Get<NetEqCapacityConfig>().capacity); 79264dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin } 7935263b3c1ddb10ecca58d9f08364aad2d6ba1d95dHenrik Lundin acm_config.neteq_config.enable_fast_accelerate = 7945263b3c1ddb10ecca58d9f08364aad2d6ba1d95dHenrik Lundin config.Get<NetEqFastAccelerate>().enabled; 79564dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin audio_coding_.reset(AudioCodingModule::Create(acm_config)); 79664dad838e61e92e4a72437b153c5eba7a200fb4aHenrik Lundin 797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.ResetDtmf(); 798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.Init(); 799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8012853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RtpRtcp::Configuration configuration; 8022853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio = true; 8032853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.outgoing_transport = this; 8042853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio_messages = this; 805822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org configuration.receive_statistics = rtp_receive_statistics_.get(); 8060a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org configuration.bandwidth_callback = rtcp_observer_.get(); 8072853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 8082853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); 80954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 81054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); 81154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->RegisterRtcpStatisticsCallback( 81254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistics_proxy_.get()); 813f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org 814f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org Config audioproc_config; 815f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); 816f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); 817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::~Channel() 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 82154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); 822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::~Channel() - dtor"); 824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kPlaybackPerChannel); 828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 829944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_external_media) 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kRecordingPerChannel); 832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopSend(); 834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopPlayout(); 835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 8379a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr) 846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->StopPlayingFile(); 849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr = NULL; 851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The order to safely shutdown modules in a channel is: 862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1. De-register callbacks in modules 863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 2. De-register modules in process thread 864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 3. Destroy modules 865eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterTransportCallback(NULL) == -1) 866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register transport callback" 870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 872eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterVADCallback(NULL) == -1) 873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register VAD callback" 877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register modules in process thread 8803985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); 8813985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org 882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // End of modules shutdown 883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete other objects 885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_callbackCritSect; 886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_fileCritSect; 88763420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org delete &volume_settings_critsect_; 888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8906141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Init() 892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init()"); 895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 896944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.Reset(); 897944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Initial sanity 899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_engineStatisticsPtr == NULL) || 901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_moduleProcessThreadPtr == NULL)) 902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() must call SetEngineInformation() first"); 906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add modules to process thread (for periodic schedulation) 910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9113985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()); 9123985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org 913c450a1966965fbb3c16ec6d02c3d5cbec67df500pwestin@webrtc.org // --- ACM initialization 914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 91545c6449114ab69cab755410f69567fa7e20f8106Henrik Lundin if ((audio_coding_->InitializeReceiver() == -1) 916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // out-of-band Dtmf tones are played out by default 9171f9baab753be55a7c6d31c84a5470fe646936eddkwiberg || (audio_coding_->SetDtmfPlayoutStatus(true) == -1)) { 918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to initialize the ACM - 1"); 921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- RTP/RTCP module initialization 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that RTCP is enabled by default for the created channel. 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the module will keep generating RTCP until it is explicitly 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // disabled by the user. 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // After StopListen (when no sockets exists), RTCP packets will no longer 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // be transmitted since the Transport object will then be invalid. 931822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org telephone_event_handler_->SetTelephoneEventForwardToDecoder(true); 932822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // RTCP is enabled by default. 933d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetRTCPStatus(kRtcpCompound); 934d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org // --- Register all permanent callbacks 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool fail = 936eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterTransportCallback(this) == -1) || 937eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterVADCallback(this) == -1); 938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fail) 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() callbacks not registered"); 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all supported codecs to the receiving side of the 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTP/RTCP module 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 9516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 956eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->Codec(idx, &codec) == -1) || 957822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rtp_receiver_->RegisterReceivePayload( 958822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 959822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 960822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 961822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 962822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) == -1)) 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to register %s (%d/%d/%d/%d) " 967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "to RTP/RTCP receiver", 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() %s (%d/%d/%d/%d) has been added to " 976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP receiver", 977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that PCMU is used as default codec on the sending side 9824517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SetSendCodec(codec); 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register default PT for outband 'telephone-event' 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "telephone-event")) 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 9902853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || 991eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterReceiveCodec(codec) == -1)) 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register outband " 996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "'telephone-event' (%d/%d) correctly", 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "CN")) 1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1003eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->RegisterSendCodec(codec) == -1) || 1004eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterReceiveCodec(codec) == -1) || 10052853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) 1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register CN (%d/%d) " 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly - 1", 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_RED 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register RED to the receiving side of the ACM. 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will not receive an OnInitializeDecoder() callback for RED. 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "RED")) 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1019eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) == -1) 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register RED (%d/%d) " 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly", 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1030684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 10316c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org if (rx_audioproc_->noise_suppression()->set_level(kDefaultNsMode) != 0) { 10326c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org LOG_FERR1(LS_ERROR, noise_suppression()->set_level, kDefaultNsMode); 10336c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org return -1; 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 10356c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org if (rx_audioproc_->gain_control()->set_mode(kDefaultRxAgcMode) != 0) { 10366c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org LOG_FERR1(LS_ERROR, gain_control()->set_mode, kDefaultRxAgcMode); 10376c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org return -1; 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10436141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetEngineInformation(Statistics& engineStatistics, 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OutputMixer& outputMixer, 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com voe::TransmitMixer& transmitMixer, 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessThread& moduleProcessThread, 1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioDeviceModule& audioDeviceModule, 1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoiceEngineObserver* voiceEngineObserver, 1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionWrapper* callbackCritSect) 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetEngineInformation()"); 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr = &engineStatistics; 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr = &outputMixer; 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transmitMixerPtr = &transmitMixer, 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _moduleProcessThreadPtr = &moduleProcessThread; 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioDeviceModulePtr = &audioDeviceModule; 1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = voiceEngineObserver; 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSectPtr = callbackCritSect; 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10646141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateLocalTimeStamp() 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1068b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_); 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10726141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartPlayout() 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayout()"); 1077944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 10811b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 10821b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 10831b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Add participant as candidates for mixing. 10841b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) 10851b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 10861b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 10871b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 10881b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StartPlayout() failed to add participant to mixer"); 10891b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 10901b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1093944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetPlaying(true); 1094ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1095ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 1096ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11006141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopPlayout() 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayout()"); 1105944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing) 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 11091b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 11101b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 11111b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Remove participant as candidates for mixing 11121b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) 11131b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 11141b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 11151b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 11161b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StopPlayout() failed to remove participant from mixer"); 11171b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 11181b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1121944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetPlaying(false); 1122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11276141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartSend() 1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartSend()"); 113209e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // Resume the previous sequence number which was reset by StopSend(). 1133944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org // This needs to be done before |sending| is set to true. 113409e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org if (send_sequence_number_) 113509e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org SetInitSequenceNumber(send_sequence_number_); 113609e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org 1137944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().sending) 1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1139944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return 0; 1140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1141944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(true); 1142e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 11432853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(true) != 0) 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to start sending"); 11489a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1149944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(false); 1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1152e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11566141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopSend() 1158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopSend()"); 1161944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().sending) 1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1163944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return 0; 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1165944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(false); 1166e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 116709e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // Store the sequence number to be able to pick up the same sequence for 116809e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // the next StartSend(). This is needed for restarting device, otherwise 116909e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // it might cause libSRTP to complain about packets being replayed. 117009e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring 117109e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // CL is landed. See issue 117209e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // https://code.google.com/p/webrtc/issues/detail?id=2111 . 117309e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org send_sequence_number_ = _rtpRtcpModule->SequenceNumber(); 117409e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset sending SSRC and sequence number and triggers direct transmission 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // of RTCP BYE 1177d436298332c7a7ecb51241f3a66588539c2ece83pbos if (_rtpRtcpModule->SetSendingStatus(false) == -1) 1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to stop sending"); 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11876141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartReceiving() 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartReceiving()"); 1192944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().receiving) 1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1196944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetReceiving(true); 1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets = 0; 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12016141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopReceiving() 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopReceiving()"); 1206944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().receiving) 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1210684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1211944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetReceiving(false); 1212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterVoiceEngineObserver()"); 12209a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterVoiceEngineObserver() observer already enabled"); 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = &observer; 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterVoiceEngineObserver() 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterVoiceEngineObserver()"); 12389a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_voiceEngineObserverPtr) 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterVoiceEngineObserver() observer already disabled"); 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = NULL; 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendCodec(CodecInst& codec) 1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1254eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org return (audio_coding_->SendCodec(&codec)); 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12576141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecCodec(CodecInst& codec) 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1260eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org return (audio_coding_->ReceiveCodec(&codec)); 1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12636141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCodec(const CodecInst& codec) 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCodec()"); 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1269eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) != 0) 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to ACM"); 1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12762853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 12782853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 12792853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to" 1284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " RTP/RTCP module"); 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12892853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to set audio packet size"); 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1299adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusenvoid Channel::SetBitRate(int bitrate_bps) { 1300adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1301adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen "Channel::SetBitRate(bitrate_bps=%d)", bitrate_bps); 1302adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen audio_coding_->SetBitRate(bitrate_bps); 1303adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen} 1304adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen 13050a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.orgvoid Channel::OnIncomingFractionLoss(int fraction_lost) { 130674aaf29a0ff1b211dbfdbb6309791111a7871779minyue@webrtc.org network_predictor_->UpdatePacketLossRate(fraction_lost); 13070a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org uint8_t average_fraction_loss = network_predictor_->GetLossRate(); 13080a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1309c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org // Normalizes rate to 0 - 100. 13100a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (audio_coding_->SetPacketLossRate( 13110a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 100 * average_fraction_loss / 255) != 0) { 1312c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org assert(false); // This should not happen. 1313c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 1314c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 1315c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 13166141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetVADStatus(mode=%d)", mode); 1321664ccb7d8da3adfffdb7c56f885b633224555e6ehenrik.lundin@webrtc.org assert(!(disableDTX && enableVAD)); // disableDTX mode is deprecated. 1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // To disable VAD, DTX must be disabled too 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disableDTX = ((enableVAD == false) ? true : disableDTX); 1324eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetVAD(!disableDTX, enableVAD, mode) != 0) 1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetVADStatus() failed to set VAD"); 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13346141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) 1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetVADStatus"); 1339eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->VAD(&disabledDTX, &enabledVAD, &mode) != 0) 1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetVADStatus() failed to get VAD status"); 1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disabledDTX = !disabledDTX; 1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13506141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRecPayloadType(const CodecInst& codec) 1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRecPayloadType()"); 1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1356944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while playing"); 1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1363944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().receiving) 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_LISTENING, kTraceError, 1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while listening"); 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codec.pltype == -1) 1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register the selected codec (RTP/RTCP module and ACM) 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13756141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t pltype(-1); 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst rxCodec = codec; 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get payload type for the given codec 1379822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_->ReceivePayloadType( 1380822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.plname, 1381822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.plfreq, 1382822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.channels, 1383822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rxCodec.rate < 0) ? 0 : rxCodec.rate, 1384822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &pltype); 1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rxCodec.pltype = pltype; 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1387822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0) 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 1391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 1392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module deregistration " 1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1396eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0) 1397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM deregistration failed - 1"); 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1406822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->RegisterReceivePayload( 1407822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1408822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 1409822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1410822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1411822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) != 0) 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // First attempt to register failed => de-register and try again 1414822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receiver_->DeRegisterReceivePayload(codec.pltype); 1415822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->RegisterReceivePayload( 1416822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1417822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 1418822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1419822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1420822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) != 0) 1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module registration failed"); 1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1428eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) != 0) 1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1430eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->UnregisterReceiveCodec(codec.pltype); 1431eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) != 0) 1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM registration failed - 1"); 1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14426141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecPayloadType(CodecInst& codec) 1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType()"); 14476141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(-1); 1448822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_payload_registry_->ReceivePayloadType( 1449822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1450822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1451822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1452822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate, 1453822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &payloadType) != 0) 1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 145637198007eab6731fa0f77866155dd4f2b332a262henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRecPayloadType() failed to retrieve RX payload type"); 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = payloadType; 1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1462d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org "Channel::GetRecPayloadType() => pltype=%d", codec.pltype); 1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14666141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCNPayloadType()"); 1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 14736141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t samplingFreqHz(-1); 14744517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org const int kMono = 1; 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (frequency == kFreq32000Hz) 1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 32000; 1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (frequency == kFreq16000Hz) 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 16000; 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1480eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1) 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to retrieve default CN codec " 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "settings"); 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Modify the payload type (must be set to dynamic range) 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = type; 1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1492eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) != 0) 1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to ACM"); 1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15002853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 15022853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 15032853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to RTP/RTCP " 1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1515adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.orgint Channel::SetOpusMaxPlaybackRate(int frequency_hz) { 15166aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1517adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org "Channel::SetOpusMaxPlaybackRate()"); 15186aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org 1519adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org if (audio_coding_->SetOpusMaxPlaybackRate(frequency_hz) != 0) { 15206aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org _engineStatisticsPtr->SetLastError( 15216aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1522adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org "SetOpusMaxPlaybackRate() failed to set maximum playback rate"); 15236aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org return -1; 15246aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org } 15256aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org return 0; 15266aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org} 15276aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org 15289b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.orgint Channel::SetOpusDtx(bool enable_dtx) { 15299b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 15309b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org "Channel::SetOpusDtx(%d)", enable_dtx); 1531092041c1cdadeb82463ee79dfc291d60b41d35efMinyue Li int ret = enable_dtx ? audio_coding_->EnableOpusDtx() 15329b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org : audio_coding_->DisableOpusDtx(); 15339b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org if (ret != 0) { 15349b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org _engineStatisticsPtr->SetLastError( 15359b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, "SetOpusDtx() failed"); 15369b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org return -1; 15379b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org } 15389b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org return 0; 15399b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org} 15409b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org 15416141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t Channel::RegisterExternalTransport(Transport& transport) 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalTransport()"); 1545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15469a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 1549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() external transport already enabled"); 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = true; 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = &transport; 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15606141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalTransport() 1562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalTransport()"); 1565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15669a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 156783661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org 1568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_transportPtr) 1569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() external transport already " 1573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "disabled"); 1574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = false; 1577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = NULL; 1578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() all transport is disabled"); 1580684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org return 0; 1581684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 1582684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 15834591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t Channel::ReceivedRTPPacket(const int8_t* data, size_t length, 1584b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org const PacketTime& packet_time) { 15850c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 15860c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTPPacket()"); 1587684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 15880c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTP packet 15891de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(false); 1590684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 15917bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* received_packet = reinterpret_cast<const uint8_t*>(data); 1592a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org RTPHeader header; 15937bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_header_parser_->Parse(received_packet, length, &header)) { 15947bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 15957bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Incoming packet: invalid RTP header"); 1596a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return -1; 1597a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } 1598822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org header.payload_type_frequency = 1599822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); 16007bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (header.payload_type_frequency < 0) 1601822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return -1; 160248df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order = IsPacketInOrder(header); 16037bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->IncomingPacket(header, length, 160448df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org IsPacketRetransmitted(header, in_order)); 16057bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_payload_registry_->SetIncomingPayloadType(header); 1606b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org 160748df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1; 16087bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 16097bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 16107bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::ReceivePacket(const uint8_t* packet, 16114591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t packet_length, 16127bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const RTPHeader& header, 16137bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org bool in_order) { 1614456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org if (rtp_payload_registry_->IsRtx(header)) { 1615456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org return HandleRtxPacket(packet, packet_length, header); 1616822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 16177bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* payload = packet + header.headerLength; 16184591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org assert(packet_length >= header.headerLength); 16194591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_length = packet_length - header.headerLength; 1620822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org PayloadUnion payload_specific; 1621822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 16227bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org &payload_specific)) { 16237bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 1624822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 16257bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 16267bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org payload_specific, in_order); 16277bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 16287bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 1629456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.orgbool Channel::HandleRtxPacket(const uint8_t* packet, 1630456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org size_t packet_length, 1631456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org const RTPHeader& header) { 16327bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_payload_registry_->IsRtx(header)) 16337bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16347bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 16357bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Remove the RTX header and parse the original RTP header. 16367bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (packet_length < header.headerLength) 16377bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16387bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (packet_length > kVoiceEngineMaxIpPacketSizeBytes) 16397bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16407bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (restored_packet_in_use_) { 16417bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 16427bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Multiple RTX headers detected, dropping packet"); 16437bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16440c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 16457bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org uint8_t* restored_packet_ptr = restored_packet_; 16467bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_payload_registry_->RestoreOriginalPacket( 16477bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(), 16487bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org header)) { 16497bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 16507bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Incoming RTX packet: invalid RTP header"); 16517bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16527bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 16537bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = true; 16547bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length); 16557bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = false; 16567bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ret; 16577bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 16587bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 16597bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::IsPacketInOrder(const RTPHeader& header) const { 16607bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 16617bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 16627bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 16637bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16647bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return statistician->IsPacketInOrder(header.sequenceNumber); 16650c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org} 16660c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 166748df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.orgbool Channel::IsPacketRetransmitted(const RTPHeader& header, 166848df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order) const { 16697bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Retransmissions are handled separately if RTX is enabled. 16707bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (rtp_payload_registry_->RtxEnabled()) 16717bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16727bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 16737bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 16747bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 16757bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 16767bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Check if this is a retransmission. 167716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t min_rtt = 0; 16787bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 167948df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org return !in_order && 16807bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org statistician->IsRetransmitOfOldPacket(header, min_rtt); 1681822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 1682822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 16834591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) { 16840c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 16850c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTCPPacket()"); 16860c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTCP packet 16871de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(true); 16880c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 16890c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Deliver RTCP packet to RTP/RTCP module for parsing 16904591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, length) == -1) { 16910c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 16920c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 16930c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::IncomingRTPPacket() RTCP packet is invalid"); 16940c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 169582c4b8531c2c4c2aaf82ff57ee1805037a43ed50wu@webrtc.org 16962013aeced2b7821a407f302802c4a16fd02728b1Minyue int64_t rtt = GetRTT(true); 16972013aeced2b7821a407f302802c4a16fd02728b1Minyue if (rtt == 0) { 16982013aeced2b7821a407f302802c4a16fd02728b1Minyue // Waiting for valid RTT. 16992013aeced2b7821a407f302802c4a16fd02728b1Minyue return 0; 17002013aeced2b7821a407f302802c4a16fd02728b1Minyue } 17012013aeced2b7821a407f302802c4a16fd02728b1Minyue uint32_t ntp_secs = 0; 17022013aeced2b7821a407f302802c4a16fd02728b1Minyue uint32_t ntp_frac = 0; 17032013aeced2b7821a407f302802c4a16fd02728b1Minyue uint32_t rtp_timestamp = 0; 17042013aeced2b7821a407f302802c4a16fd02728b1Minyue if (0 != _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, 17052013aeced2b7821a407f302802c4a16fd02728b1Minyue &rtp_timestamp)) { 17062013aeced2b7821a407f302802c4a16fd02728b1Minyue // Waiting for RTCP. 17072013aeced2b7821a407f302802c4a16fd02728b1Minyue return 0; 17082013aeced2b7821a407f302802c4a16fd02728b1Minyue } 17092013aeced2b7821a407f302802c4a16fd02728b1Minyue 17108e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org { 17118e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 17122c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); 17138e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org } 17140c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org return 0; 1715684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 1716684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(const char* fileName, 17189213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 17199213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 17209213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 17219213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 17229213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 1723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 1724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," 1727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " format=%d, volumeScaling=%5.3f, startPosition=%d, " 1728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 1729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 1730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1731944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 1732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 1736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 17409a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1742b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 1743b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1744b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1745b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1746b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1747b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1749b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 1750b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, (const FileFormats)format); 1751b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1752b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 1753b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1754b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1755b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 175631d30700d638c4cfa47c26cac7cb00c7232874c9henrike@webrtc.org "StartPlayingFileLocally() filePlayer format is not correct"); 1757b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1758b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 17606141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 1761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1762b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile( 1763b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org fileName, 1764b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org loop, 1765b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org startPosition, 1766b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 1767b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 1768b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, 1769b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const CodecInst*)codecInst) != 0) 1770b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1771b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1772b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_BAD_FILE, kTraceError, 1773b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to start file playout"); 1774b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 1775b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1776b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1777b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1778b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1779b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 1780944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(true); 1781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1782ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1783ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1784066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(InStream* stream, 17909213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 17919213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 17929213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 17939213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 1794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 1795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(format=%d," 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 1802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() NULL as input stream"); 1806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1810944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 1815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 18199a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1820b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1821b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Destroy the old instance 1822b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 1823b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1824b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1825b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1826b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1827b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1828b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1829b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Create the instance 1830b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 1831b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, 1832b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const FileFormats)format); 1833b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1834b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 1835b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1836b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1837b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 1838b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFileLocally() filePlayer format isnot correct"); 1839b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1840b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1841b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 18426141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 1843b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1844b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 1845b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 1846b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 1847b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, codecInst) != 0) 1848b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1849b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 1850b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to " 1851b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "start file playout"); 1852b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 1853b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1854b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1855b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1856b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1857b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 1858944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(true); 1859b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1860ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1861ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1862066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileLocally() 1868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileLocally()"); 1871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1872944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().output_file_playing) 1873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileLocally() isnot playing"); 1877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 18819a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1882b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1883b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StopPlayingFile() != 0) 1884b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1885b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1886b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 1887b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() could not stop playing"); 1888b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1889b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1890b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1891b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1892b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1893944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 1894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1895b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // _fileCritSect cannot be taken while calling 1896b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // SetAnonymousMixibilityStatus. Refer to comments in 1897b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // StartPlayingFileLocally(const char* ...) for more details. 1898066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) 1899066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org { 1900066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org _engineStatisticsPtr->SetLastError( 1901066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1902b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() failed to stop participant from playing as" 1903b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "file in the mixer"); 1904066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1905066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org } 1906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileLocally() const 1911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileLocally()"); 1914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1915944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return channel_state_.Get().output_file_playing; 1916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1918ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.orgint Channel::RegisterFilePlayingToMixer() 1919ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org{ 1920ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // Return success for not registering for file playing to mixer if: 1921ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 1. playing file before playout is started on that channel. 1922ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 2. starting playout without file playing on that channel. 1923944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing || 1924944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org !channel_state_.Get().output_file_playing) 1925ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 1926ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 1927ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 1928ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1929ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // |_fileCritSect| cannot be taken while calling 1930ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // SetAnonymousMixabilityStatus() since as soon as the participant is added 1931ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // frames can be pulled by the mixer. Since the frames are generated from 1932ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // the file, _fileCritSect will be taken. This would result in a deadlock. 1933ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) 1934ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 1935944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 1936ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1937ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _engineStatisticsPtr->SetLastError( 1938ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1939ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org "StartPlayingFile() failed to add participant as file to mixer"); 1940ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 1941ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1942ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr = NULL; 1943ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 1944ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 1945ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1946ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 1947ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org} 1948ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(const char* fileName, 19509213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 19519213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 19529213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 19539213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 19549213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 1956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " 1959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " 1960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 1961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 1962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1963944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1964944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 1965944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_file_playing) 1966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer is playing"); 1970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 1974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 1975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 1978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 1979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() filePlayer format isnot correct"); 1990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 19936141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 1994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile( 1996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, 1997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com loop, 1998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, 1999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, 2000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime, 2001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, 2002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const CodecInst*)codecInst) != 0) 2003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start file playout"); 2007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2013944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(true); 2014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(InStream* stream, 20199213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 20209213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 20219213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 20229213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(format=%d, " 2027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 2028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 2029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 2031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone NULL as input stream"); 2035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2038944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2039944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 2040944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_file_playing) 2041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 2044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() is playing"); 2045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 2050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 2057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 2059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 2061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingInputFile() filePlayer format isnot correct"); 2065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 20686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 2071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, notificationTime, 2072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, codecInst) != 0) 2073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start " 2076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "file playout"); 2077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2082ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2084944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(true); 2085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileAsMicrophone() 2090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileAsMicrophone()"); 2093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2094944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2095944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 2096944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().input_file_playing) 2097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileAsMicrophone() isnot playing"); 2101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StopPlayingFile() != 0) 2105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFile() could not stop playing"); 2109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2114944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(false); 2115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileAsMicrophone() const 2120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileAsMicrophone()"); 2123944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return channel_state_.Get().input_file_playing; 2124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2126813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.orgint Channel::StartRecordingPlayout(const char* fileName, 2127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout(fileName=%s)", fileName); 2131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 21406141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 214340197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org if ((codecInst != NULL) && 214440197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org ((codecInst->channels < 1) || (codecInst->channels > 2))) 2145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21679a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile( 2188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, (const CodecInst&)*codecInst, notificationTime) != 0) 2189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingAudioFile() failed to start file recording"); 2193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartRecordingPlayout(OutStream* stream, 2205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout()"); 2209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 22186141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codecInst != NULL && codecInst->channels != 1) 2222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22449a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, 2265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime) != 0) 2266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() failed to " 2269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "start file recording"); 2270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2275ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopRecordingPlayout() 2283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 2285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRecordingPlayout()"); 2286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFileRecording) 2288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), 2290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecordingPlayout() isnot recording"); 2291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22959a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StopRecording() != 0) 2298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecording() could not stop recording"); 2302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 2308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 2313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMixWithMicStatus(bool mix) 2314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2315944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mixFileWithMicrophone=mix; 2317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 23206141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevel(uint32_t& level) const 2321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 23226141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t currentLevel = _outputAudioLevel.Level(); 23236141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 2324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevel() => level=%u", level); 2327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 23316141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevelFullRange(uint32_t& level) const 2332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 23336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t currentLevel = _outputAudioLevel.LevelFullRange(); 23346141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 2335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevelFullRange() => level=%u", level); 2338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMute(bool enable) 2343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 234463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMute(enable=%d)", enable); 2347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute = enable; 2348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 2352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Mute() const 2353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 235463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _mute; 2356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOutputVolumePan(float left, float right) 2360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 236163420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOutputVolumePan()"); 2364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft = left; 2365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight = right; 2366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOutputVolumePan(float& left, float& right) const 2371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 237263420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com left = _panLeft; 2374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com right = _panRight; 2375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetOutputVolumePan() => left=%3.2f, right=%3.2f", left, right); 2378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetChannelOutputVolumeScaling(float scaling) 2383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 238463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetChannelOutputVolumeScaling()"); 2387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain = scaling; 2388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetChannelOutputVolumeScaling(float& scaling) const 2393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 239463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaling = _outputGain; 2396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetChannelOutputVolumeScaling() => scaling=%3.2f", scaling); 2399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventOutband(unsigned char eventCode, 2403822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org int lengthMs, int attenuationDb, 2404822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org bool playDtmfEvent) 2405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", 2408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 2409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent = playDtmfEvent; 2411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 24122853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, 2413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb) != 0) 2414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_DTMF_FAILED, 2417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 2418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendTelephoneEventOutband() failed to send event"); 2419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventInband(unsigned char eventCode, 2425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, 2426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int attenuationDb, 2427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 2428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", 2431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 2432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent = playDtmfEvent; 2434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); 2435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendTelephoneEventPayloadType(unsigned char type) 2441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendTelephoneEventPayloadType()"); 2444f81f9f8c2a18fb20ee60406ece45ff3210367ff9andrew@webrtc.org if (type > 127) 2445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTelephoneEventPayloadType() invalid type"); 2449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 24515b10d8fb184db0192091bf407c8166b5d03b932epbos@webrtc.org CodecInst codec = {}; 24521da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.plfreq = 8000; 24531da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.pltype = type; 24541da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org memcpy(codec.plname, "telephone-event", 16); 24552853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 24574392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 24584392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { 24594392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _engineStatisticsPtr->SetLastError( 24604392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 24614392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "SetSendTelephoneEventPayloadType() failed to register send" 24624392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "payload type"); 24634392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org return -1; 24644392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org } 2465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTelephoneEventPayloadType = type; 2467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendTelephoneEventPayloadType(unsigned char& type) 2472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendTelephoneEventPayloadType()"); 2475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com type = _sendTelephoneEventPayloadType; 2476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTelephoneEventPayloadType() => type=%u", type); 2479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateRxVadDetection(AudioFrame& audioFrame) 2484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection()"); 2487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int vadDecision = 1; 2489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 249063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; 2491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) 2493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OnRxVadDetected(vadDecision); 2495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _oldVadDecision = vadDecision; 2496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection() => vadDecision=%d", 2500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com vadDecision); 2501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRxVadObserver(VoERxVadCallback &observer) 2506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRxVadObserver()"); 25099a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 2512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRxVadObserver() observer already enabled"); 2516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = &observer; 2519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = true; 2520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRxVadObserver() 2525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRxVadObserver()"); 25289a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rxVadObserverPtr) 2531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRxVadObserver() observer already disabled"); 2535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = NULL; 2538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = false; 2539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::VoiceActivityIndicator(int &activity) 2544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com activity = _sendFrameType; 2546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 25486c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "Channel::VoiceActivityIndicator(indicator=%d)", activity); 2549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_AGC 2553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 25559213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcStatus(bool enable, AgcModes mode) 2556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcStatus(enable=%d, mode=%d)", 2559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 2560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 25616c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org GainControl::Mode agcMode = kDefaultRxAgcMode; 2562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcDefault: 2565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcUnchanged: 2567f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org agcMode = rx_audioproc_->gain_control()->mode(); 2568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcFixedDigital: 2570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kFixedDigital; 2571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcAdaptiveDigital: 2573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode =GainControl::kAdaptiveDigital; 2574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() invalid Agc mode"); 2579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2582f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_mode(agcMode) != 0) 2583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc mode"); 2587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2589f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->Enable(enable) != 0) 2590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 2594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled = enable; 2598944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); 2599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcStatus(bool& enabled, AgcModes& mode) 2605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcStatus(enable=?, mode=?)"); 2608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2609f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org bool enable = rx_audioproc_->gain_control()->is_enabled(); 2610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode = 2611f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->mode(); 2612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 2614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (agcMode) 2616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kFixedDigital: 2618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcFixedDigital; 2619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kAdaptiveDigital: 2621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcAdaptiveDigital; 2622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxAgcStatus() invalid Agc mode"); 2627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 26349213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcConfig(AgcConfig config) 2635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcConfig()"); 2638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2639f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_target_level_dbfs( 2640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv) != 0) 2641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set target peak |level|" 2645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "(or envelope) of the Agc"); 2646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2648f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_compression_gain_db( 2649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB) != 0) 2650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set the range in |gain| the" 2654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " digital compression stage may apply"); 2655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2657f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->enable_limiter( 2658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable) != 0) 2659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set hard limiter to the signal"); 2663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcConfig(AgcConfig& config) 2671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcConfig(config=%?)"); 2674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv = 2676f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->target_level_dbfs(); 2677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB = 2678f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->compression_gain_db(); 2679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable = 2680f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->is_limiter_enabled(); 2681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), "GetRxAgcConfig() => " 2684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "targetLeveldBOv=%u, digitalCompressionGaindB=%u," 2685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " limiterEnable=%d", 2686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv, 2687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB, 2688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable); 2689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC 2694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_NR 2696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 26989213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxNsStatus(bool enable, NsModes mode) 2699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxNsStatus(enable=%d, mode=%d)", 2702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 2703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27046c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org NoiseSuppression::Level nsLevel = kDefaultNsMode; 2705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsDefault: 2709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsUnchanged: 2711f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org nsLevel = rx_audioproc_->noise_suppression()->level(); 2712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsConference: 2714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 2715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsLowSuppression: 2717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kLow; 2718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsModerateSuppression: 2720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kModerate; 2721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsHighSuppression: 2723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 2724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsVeryHighSuppression: 2726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kVeryHigh; 2727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2730f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->noise_suppression()->set_level(nsLevel) 2731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 2732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 27356c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "SetRxNsStatus() failed to set NS level"); 2736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2738f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->noise_suppression()->Enable(enable) != 0) 2739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 27426c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "SetRxNsStatus() failed to set NS state"); 2743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxNsIsEnabled = enable; 2747944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); 2748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxNsStatus(bool& enabled, NsModes& mode) 2754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxNsStatus(enable=?, mode=?)"); 2757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = 2759f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->noise_suppression()->is_enabled(); 2760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level ncLevel = 2761f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->noise_suppression()->level(); 2762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 2764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (ncLevel) 2766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kLow: 2768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsLowSuppression; 2769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kModerate: 2771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsModerateSuppression; 2772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kHigh: 2774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsHighSuppression; 2775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kVeryHigh: 2777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsVeryHighSuppression; 2778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxNsStatus() => enabled=%d, mode=%d", enabled, mode); 2784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_NR 2788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetLocalSSRC(unsigned int ssrc) 2791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetLocalSSRC()"); 2794944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().sending) 2795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_SENDING, kTraceError, 2798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() already sending"); 2799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2801ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org _rtpRtcpModule->SetSSRC(ssrc); 2802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetLocalSSRC(unsigned int& ssrc) 2807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 28082853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->SSRC(); 2809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalSSRC() => ssrc=%lu", ssrc); 2812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteSSRC(unsigned int& ssrc) 2817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2818822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org ssrc = rtp_receiver_->SSRC(); 2819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteSSRC() => ssrc=%lu", ssrc); 2822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2825ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) { 2826f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org _includeAudioLevelIndication = enable; 2827ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id); 2828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2829f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org 283093fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.orgint Channel::SetReceiveAudioLevelIndicationStatus(bool enable, 283193fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org unsigned char id) { 283293fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org rtp_header_parser_->DeregisterRtpHeaderExtension( 283393fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org kRtpExtensionAudioLevel); 283493fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( 283593fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org kRtpExtensionAudioLevel, id)) { 283693fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org return -1; 283793fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org } 283893fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org return 0; 283993fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org} 284093fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org 2841ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) { 2842ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return SetSendRtpHeaderExtension(enable, kRtpExtensionAbsoluteSendTime, id); 2843ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org} 2844ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org 2845ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id) { 2846ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org rtp_header_parser_->DeregisterRtpHeaderExtension( 2847ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org kRtpExtensionAbsoluteSendTime); 2848b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( 2849b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org kRtpExtensionAbsoluteSendTime, id)) { 2850b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org return -1; 2851ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org } 2852ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return 0; 2853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2855d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid Channel::SetRTCPStatus(bool enable) { 2856d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2857d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "Channel::SetRTCPStatus()"); 2858d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetRTCPStatus(enable ? kRtcpCompound : kRtcpOff); 2859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCPStatus(bool& enabled) 2863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 28642853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 2865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (method != kRtcpOff); 2866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCPStatus() => enabled=%d", enabled); 2869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCP_CNAME(const char cName[256]) 2874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCP_CNAME()"); 28772853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetCNAME(cName) != 0) 2878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCP_CNAME() failed to set RTCP CNAME"); 2882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCP_CNAME(char cName[256]) 2889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cName == NULL) 2891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); 2895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2897813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char cname[RTCP_CNAME_SIZE]; 2898822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org const uint32_t remoteSSRC = rtp_receiver_->SSRC(); 28992853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) 2900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_CNAME, kTraceError, 2903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); 2904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(cName, cname); 2907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 2909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() => cName=%s", cName); 2910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCPData( 2915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPHigh, 2916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPLow, 2917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& timestamp, 2918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& playoutTimestamp, 2919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int* jitter, 2920470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short* fractionLost) 2921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Information from sender info in received Sender Reports 2923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPSenderInfo senderInfo; 29252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) 2926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2929fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRemoteRTCPData() failed to retrieve sender info for remote " 2930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "side"); 2931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We only utilize 12 out of 20 bytes in the sender info (ignores packet 2935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and octet count) 2936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh = senderInfo.NTPseconds; 2937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPLow = senderInfo.NTPfraction; 2938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp = senderInfo.RTPtimeStamp; 2939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 2942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " 2943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "timestamp=%lu", 2944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh, NTPLow, timestamp); 2945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Locally derived information 2947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This value is updated on each incoming RTCP packet (0 when no packet 2949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has been received) 29501de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playoutTimestamp = playout_timestamp_rtcp_; 2951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 2954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => playoutTimestamp=%lu", 29551de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_); 2956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL != jitter || NULL != fractionLost) 2958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2959ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Get all RTCP receiver report blocks that have been received on this 2960ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // channel. If we receive RTP packets from a remote source we know the 2961ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // remote SSRC and use the report block from him. 2962ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Otherwise use the first report block. 2963ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock> remote_stats; 29642853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || 2965ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remote_stats.empty()) { 2966ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 2967ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org VoEId(_instanceId, _channelId), 2968ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org "GetRemoteRTCPData() failed to measure statistics due" 2969ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org " to lack of received RTP and/or RTCP packets"); 2970ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org return -1; 2971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2972ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 2973822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org uint32_t remoteSSRC = rtp_receiver_->SSRC(); 2974ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin(); 2975ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org for (; it != remote_stats.end(); ++it) { 2976ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it->remoteSSRC == remoteSSRC) 2977ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org break; 2978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2979ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 2980ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it == remote_stats.end()) { 2981ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // If we have not received any RTCP packets from this SSRC it probably 2982ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // means that we have not received any RTP packets. 2983ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Use the first received report block instead. 2984ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org it = remote_stats.begin(); 2985ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remoteSSRC = it->remoteSSRC; 2986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2987ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 298879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (jitter) { 298979af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *jitter = it->jitter; 299079af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 299179af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 299279af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => jitter = %lu", *jitter); 299379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 2994ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 299579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (fractionLost) { 299679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost = it->fractionLost; 299779af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 299879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 299979af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => fractionLost = %lu", 300079af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost); 300179af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 3002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 30079213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SendApplicationDefinedRTCPPacket(unsigned char subType, 3008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int name, 3009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* data, 3010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short dataLengthInBytes) 3011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendApplicationDefinedRTCPPacket()"); 3014944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().sending) 3015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 3018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() not sending"); 3019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL == data) 3022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid data value"); 3026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (dataLengthInBytes % 4 != 0) 3029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid length value"); 3033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 30352853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod status = _rtpRtcpModule->RTCP(); 3036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status == kRtcpOff) 3037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTCP_ERROR, kTraceError, 3040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() RTCP is disabled"); 3041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create and schedule the RTCP APP packet for transmission 30452853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPApplicationSpecificData( 3046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 3047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 3048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const unsigned char*) data, 3049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataLengthInBytes) != 0) 3050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_ERROR, kTraceError, 3053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); 3054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics( 3061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& averageJitterMs, 3062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& maxJitterMs, 3063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& discardedPackets) 3064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 3066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 306754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (_rtpRtcpModule->RTCP() == kRtcpOff) { 306854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // If RTCP is off, there is no timed thread in the RTCP module regularly 306954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // generating new stats, trigger the update manually here instead. 307054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org StreamStatistician* statistician = 307154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); 307254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (statistician) { 307354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Don't use returned statistics, use data from proxy instead so that 307454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // max jitter can be fetched atomically. 307554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics s; 307654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistician->GetStatistics(&s, true); 307754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 3078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 308054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics stats = statistics_proxy_->GetStats(); 3081eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org const int32_t playoutFrequency = audio_coding_->PlayoutFrequency(); 308254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (playoutFrequency > 0) { 308354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Scale RTP statistics given the current playout frequency 308454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org maxJitterMs = stats.max_jitter / (playoutFrequency / 1000); 308554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000); 3086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com discardedPackets = _numberOfDiscardedPackets; 3089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => averageJitterMs = %lu, maxJitterMs = %lu," 3093fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " discardedPackets = %lu)", 3094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs, maxJitterMs, discardedPackets); 3095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 30988a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPReportBlocks( 30998a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<ReportBlock>* report_blocks) { 31008a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (report_blocks == NULL) { 31018a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 31028a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlock()s invalid report_blocks."); 31038a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 31048a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 31058a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31068a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the report blocks from the latest received RTCP Sender or Receiver 31078a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Report. Each element in the vector contains the sender's SSRC and a 31088a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // report block according to RFC 3550. 31098a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock> rtcp_report_blocks; 31108a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) { 31118a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 31128a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlocks() failed to read RTCP SR/RR report block."); 31138a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 31148a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 31158a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31168a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (rtcp_report_blocks.empty()) 31178a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 31188a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31198a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin(); 31208a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org for (; it != rtcp_report_blocks.end(); ++it) { 31218a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org ReportBlock report_block; 31228a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.sender_SSRC = it->remoteSSRC; 31238a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.source_SSRC = it->sourceSSRC; 31248a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.fraction_lost = it->fractionLost; 31258a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.cumulative_num_packets_lost = it->cumulativeLost; 31268a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.extended_highest_sequence_number = it->extendedHighSeqNum; 31278a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.interarrival_jitter = it->jitter; 31288a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.last_SR_timestamp = it->lastSR; 31298a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.delay_since_last_SR = it->delaySinceLastSR; 31308a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_blocks->push_back(report_block); 31318a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 31328a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 31338a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 31348a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 3135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics(CallStatistics& stats) 3137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3138cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- RtcpStatistics 3139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 3141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 314254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics statistics; 3143286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician* statistician = 3144286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); 3145286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (!statistician || !statistician->GetStatistics( 3146822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) { 3147822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org _engineStatisticsPtr->SetLastError( 3148822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 3149822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org "GetRTPStatistics() failed to read RTP statistics from the " 3150822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org "RTP/RTCP module"); 3151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3153822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.fractionLost = statistics.fraction_lost; 3154822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.cumulativeLost = statistics.cumulative_lost; 3155822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.extendedMax = statistics.extended_max_sequence_number; 3156822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.jitterSamples = statistics.jitter; 3157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => fractionLost=%lu, cumulativeLost=%lu," 3161fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " extendedMax=%lu, jitterSamples=%li)", 3162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost, stats.cumulativeLost, stats.extendedMax, 3163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples); 3164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3165cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- RTT 31662013aeced2b7821a407f302802c4a16fd02728b1Minyue stats.rttMs = GetRTT(true); 31676fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org if (stats.rttMs == 0) { 31686fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), 31696fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org "GetRTPStatistics() failed to get RTT"); 31706fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org } else { 31716fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), 317216825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org "GetRTPStatistics() => rttMs=%" PRId64, stats.rttMs); 31736fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org } 3174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3175cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- Data counters 3176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 31774591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytesSent(0); 31786141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsSent(0); 31794591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytesReceived(0); 31806141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsReceived(0); 3181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3182286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (statistician) { 3183286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->GetDataCounters(&bytesReceived, &packetsReceived); 3184286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 3185822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 31862853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DataCountersRTP(&bytesSent, 3187822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &packetsSent) != 0) 3188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to retrieve RTP datacounters =>" 3192fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " output will not be complete"); 3193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent = bytesSent; 3196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsSent = packetsSent; 3197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesReceived = bytesReceived; 3198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived = packetsReceived; 3199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 32024591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "GetRTPStatistics() => bytesSent=%" PRIuS ", packetsSent=%d," 32034591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org " bytesReceived=%" PRIuS ", packetsReceived=%d)", 3204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent, stats.packetsSent, stats.bytesReceived, 3205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived); 3206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3207cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- Timestamps 3208cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org { 3209cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 3210cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_; 3211cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 3212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3215c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgint Channel::SetREDStatus(bool enable, int redPayloadtype) { 321642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3217c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "Channel::SetREDStatus()"); 321842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 32198c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (enable) { 32208c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (redPayloadtype < 0 || redPayloadtype > 127) { 32218c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 32228c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_PLTYPE_ERROR, kTraceError, 3223c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "SetREDStatus() invalid RED payload type"); 32248c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 32258c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 32268c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org 32278c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (SetRedPayloadType(redPayloadtype) < 0) { 32288c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 32298c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 32308c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 32318c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 32328c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 323342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 32342cf22a6abce2d38e673505a4cfd5624a3710b5cdperkj@webrtc.org 3235aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org if (audio_coding_->SetREDStatus(enable) != 0) { 323642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 323742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3238aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org "SetREDStatus() failed to set RED state in the ACM"); 323942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 324042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 324142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 3242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3245c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgChannel::GetREDStatus(bool& enabled, int& redPayloadtype) 3246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3247aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org enabled = audio_coding_->REDStatus(); 3248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 3249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 32506141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(0); 32512853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendREDPayloadType(payloadType) != 0) 3252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3255c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() failed to retrieve RED PT from RTP/RTCP " 3256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 3257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3259df9a41d2701d321dbc987201ec7cffe2a16bd2c4pkasting@chromium.org redPayloadtype = payloadType; 3260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3262c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() => enabled=%d, redPayloadtype=%d", 3263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, redPayloadtype); 3264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3268c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() => enabled=%d", enabled); 3269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3272c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgint Channel::SetCodecFECStatus(bool enable) { 3273c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3274c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "Channel::SetCodecFECStatus()"); 3275c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3276c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org if (audio_coding_->SetCodecFEC(enable) != 0) { 3277c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org _engineStatisticsPtr->SetLastError( 3278c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3279c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "SetCodecFECStatus() failed to set FEC state"); 3280c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return -1; 3281c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 3282c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return 0; 3283c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 3284c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3285c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgbool Channel::GetCodecFECStatus() { 3286c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org bool enabled = audio_coding_->CodecFEC(); 3287c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3288c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org VoEId(_instanceId, _channelId), 3289c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetCodecFECStatus() => enabled=%d", enabled); 3290c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return enabled; 3291c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 3292c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3293db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.orgvoid Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) { 3294db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org // None of these functions can fail. 3295db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets); 32967bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->SetMaxReorderingThreshold(maxNumberOfPackets); 32977bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); 3298d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org if (enable) 3299eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->EnableNack(maxNumberOfPackets); 3300d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org else 3301eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->DisableNack(); 3302db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org} 3303db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org 3304d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org// Called when we are missing one or more packets. 3305d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.orgint Channel::ResendPackets(const uint16_t* sequence_numbers, int length) { 3306db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org return _rtpRtcpModule->SendNACK(sequence_numbers, length); 3307db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org} 3308db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org 33096141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 3310755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.orgChannel::Demultiplex(const AudioFrame& audioFrame) 3311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3313755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Channel::Demultiplex()"); 3314ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.CopyFrom(audioFrame); 331563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 3316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 33192f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.orgvoid Channel::Demultiplex(const int16_t* audio_data, 33208fff1f065ea9d25970c3839294acdd606a5ddf22xians@webrtc.org int sample_rate, 3321dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t number_of_frames, 33228fff1f065ea9d25970c3839294acdd606a5ddf22xians@webrtc.org int number_of_channels) { 33232f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org CodecInst codec; 33242f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org GetSendCodec(codec); 33252f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org 332640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!mono_recording_audio_.get()) { 332740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Temporary space for DownConvertToCodecFormat. 332840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mono_recording_audio_.reset(new int16_t[kMaxMonoDataSizeSamples]); 33292f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org } 333040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org DownConvertToCodecFormat(audio_data, 333140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org number_of_frames, 333240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org number_of_channels, 333340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org sample_rate, 333440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codec.channels, 333540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codec.plfreq, 333640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mono_recording_audio_.get(), 333740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org &input_resampler_, 333840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org &_audioFrame); 33392f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org} 33402f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org 33416141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 33420b0665acc1464d68e878f203bbc8772a0e32402dxians@google.comChannel::PrepareEncodeAndSend(int mixingFrequency) 3343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend()"); 3346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 334763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 3348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend() invalid audio frame"); 3351eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3354944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_file_playing) 3355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MixOrReplaceAudioWithFile(mixingFrequency); 3357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 335921299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org bool is_muted = Mute(); // Cache locally as Mute() takes a lock. 336021299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org if (is_muted) { 336121299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org AudioFrameOperations::Mute(_audioFrame); 3362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3364944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_external_media) 3365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 33669a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 336763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (_audioFrame.num_channels_ == 2); 3368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 3369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr->Process( 3371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 3372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRecordingPerChannel, 33736141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (int16_t*)_audioFrame.data_, 337463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.samples_per_channel_, 337563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.sample_rate_hz_, 3376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 3377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com InsertInbandDtmfTone(); 3381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 338260730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org if (_includeAudioLevelIndication) { 3383dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t length = 3384dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; 338521299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org if (is_muted) { 338621299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org rms_level_.ProcessMuted(length); 338721299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org } else { 338821299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org rms_level_.Process(_audioFrame.data_, length); 338921299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org } 3390755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 3391755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 3392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 33956141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 3396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EncodeAndSend() 3397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend()"); 3400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 340163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.num_channels_ <= 2); 340263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 3403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() invalid audio frame"); 3406eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 340963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 3410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. 3412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The ACM resamples internally. 341463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.timestamp_ = _timeStamp; 3415f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // This call will trigger AudioPacketizationCallback::SendData if encoding 3416f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // is done and payload is ready for packetization and transmission. 3417f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // Otherwise, it will return without invoking the callback. 3418f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0) 3419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 3421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() ACM encoding failed"); 3422eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3425b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_); 3426f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org return 0; 3427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 34292013aeced2b7821a407f302802c4a16fd02728b1Minyuevoid Channel::DisassociateSendChannel(int channel_id) { 34302013aeced2b7821a407f302802c4a16fd02728b1Minyue CriticalSectionScoped lock(assoc_send_channel_lock_.get()); 34312013aeced2b7821a407f302802c4a16fd02728b1Minyue Channel* channel = associate_send_channel_.channel(); 34322013aeced2b7821a407f302802c4a16fd02728b1Minyue if (channel && channel->ChannelId() == channel_id) { 34332013aeced2b7821a407f302802c4a16fd02728b1Minyue // If this channel is associated with a send channel of the specified 34342013aeced2b7821a407f302802c4a16fd02728b1Minyue // Channel ID, disassociate with it. 34352013aeced2b7821a407f302802c4a16fd02728b1Minyue ChannelOwner ref(NULL); 34362013aeced2b7821a407f302802c4a16fd02728b1Minyue associate_send_channel_ = ref; 34372013aeced2b7821a407f302802c4a16fd02728b1Minyue } 34382013aeced2b7821a407f302802c4a16fd02728b1Minyue} 34392013aeced2b7821a407f302802c4a16fd02728b1Minyue 3440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::RegisterExternalMediaProcessing( 3441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessingTypes type, 3442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEMediaProcess& processObject) 3443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing()"); 3446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 34479a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 3450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 3452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 3456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 3457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = &processObject; 3460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = true; 3461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 3463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 3465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 3469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 3470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = &processObject; 3473944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputExternalMedia(true); 3474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) 3479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing()"); 3482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 34839a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 3486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputExternalMediaCallbackPtr) 3488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 3492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already disabled"); 3493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = false; 3496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = NULL; 3497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 3499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputExternalMediaCallbackPtr) 3501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 3505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "input external media already disabled"); 3506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3508944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputExternalMedia(false); 3509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = NULL; 3510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 35151b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.comint Channel::SetExternalMixing(bool enabled) { 35161b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 35171b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing(enabled=%d)", enabled); 35181b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 3519944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 35201b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 35211b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 35221b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_INVALID_OPERATION, kTraceError, 35231b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing() " 35241b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "external mixing cannot be changed while playing."); 35251b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 35261b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 35271b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 35281b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing = enabled; 35291b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 35301b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return 0; 35311b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com} 35321b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 3533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetworkStatistics(NetworkStatistics& stats) 3535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetworkStatistics()"); 3538c0bd7be0df67735d63f5cdd302a3b85f88239874minyue@webrtc.org return audio_coding_->GetNetworkStatistics(&stats); 3539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 354124301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.orgvoid Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { 354224301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org audio_coding_->GetDecodingCallStatistics(stats); 354324301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org} 354424301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org 35451de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgbool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, 35461de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org int* playout_buffer_delay_ms) const { 3547743758816853df2040a21c5652b0d0e238b1512fdeadbeef CriticalSectionScoped cs(video_sync_lock_.get()); 35481de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_average_jitter_buffer_delay_us == 0) { 3549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 35501de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate() no valid estimate."); 35511de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return false; 35521de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 35531de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 + 35541de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _recPacketDelayMs; 35551de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *playout_buffer_delay_ms = playout_delay_ms_; 35561de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 35571de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate()"); 35581de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return true; 3559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3561743758816853df2040a21c5652b0d0e238b1512fdeadbeefint Channel::LeastRequiredDelayMs() const { 3562743758816853df2040a21c5652b0d0e238b1512fdeadbeef return audio_coding_->LeastRequiredDelayMs(); 3563743758816853df2040a21c5652b0d0e238b1512fdeadbeef} 3564743758816853df2040a21c5652b0d0e238b1512fdeadbeef 35656388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgint Channel::SetInitialPlayoutDelay(int delay_ms) 35666388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org{ 35676388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 35686388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "Channel::SetInitialPlayoutDelay()"); 35696388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) || 35706388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs)) 35716388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 35726388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 35736388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 35746388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() invalid min delay"); 35756388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 35766388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 3577eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetInitialPlayoutDelay(delay_ms) != 0) 35786388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 35796388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 35806388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 35816388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() failed to set min playout delay"); 35826388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 35836388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 35846388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return 0; 35856388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org} 35866388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 35876388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 3588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMinimumPlayoutDelay(int delayMs) 3590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMinimumPlayoutDelay()"); 3593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || 3594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) 3595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() invalid min delay"); 3599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3601eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) 3602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() failed to set min playout delay"); 3606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36111de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgint Channel::GetPlayoutTimestamp(unsigned int& timestamp) { 36121de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 36131de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetPlayoutTimestamp()"); 3614743758816853df2040a21c5652b0d0e238b1512fdeadbeef uint32_t playout_timestamp_rtp = 0; 3615743758816853df2040a21c5652b0d0e238b1512fdeadbeef { 3616743758816853df2040a21c5652b0d0e238b1512fdeadbeef CriticalSectionScoped cs(video_sync_lock_.get()); 3617743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_timestamp_rtp = playout_timestamp_rtp_; 3618743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3619743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (playout_timestamp_rtp == 0) { 36201de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 36211de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 36221de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() failed to retrieve timestamp"); 36231de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return -1; 36241de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 3625743758816853df2040a21c5652b0d0e238b1512fdeadbeef timestamp = playout_timestamp_rtp; 36261de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 36271de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VoEId(_instanceId,_channelId), 36281de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() => timestamp=%u", timestamp); 36291de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return 0; 3630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3632d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint Channel::SetInitTimestamp(unsigned int timestamp) { 3633d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitTimestamp()"); 3635d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org if (channel_state_.Get().sending) { 3636d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _engineStatisticsPtr->SetLastError(VE_SENDING, kTraceError, 3637d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "SetInitTimestamp() already sending"); 3638d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return -1; 3639d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org } 3640d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetStartTimestamp(timestamp); 3641d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return 0; 3642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3644d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint Channel::SetInitSequenceNumber(short sequenceNumber) { 3645d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3646d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "Channel::SetInitSequenceNumber()"); 3647d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org if (channel_state_.Get().sending) { 3648d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _engineStatisticsPtr->SetLastError( 3649d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org VE_SENDING, kTraceError, "SetInitSequenceNumber() already sending"); 3650d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return -1; 3651d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org } 3652d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetSequenceNumber(sequenceNumber); 3653d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return 0; 3654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3657822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgChannel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const 3658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRtpRtcp()"); 3661822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org *rtpRtcpModule = _rtpRtcpModule.get(); 3662822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org *rtp_receiver = rtp_receiver_.get(); 3663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3666e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use 3667e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// a shared helper. 36686141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 36699213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::MixOrReplaceAudioWithFile(int mixingFrequency) 3670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 367100b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[640]); 3672dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t fileSamples(0); 3673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 36759a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 3678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() fileplayer" 3682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " doesnt exist"); 3683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3686d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 3687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 3688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 3689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file mixing " 3693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 3694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fileSamples == 0) 3697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file is ended"); 3701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 370563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == fileSamples); 3706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mixFileWithMicrophone) 3708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3709d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3710d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 371140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixWithSat(_audioFrame.data_, 371240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.num_channels_, 371340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 371440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1, 371540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples); 3716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3719d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Replace ACM audio with file. 3720d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3721d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 3722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioFrame.UpdateFrame(_channelId, 3723eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org 0xFFFFFFFF, 3724d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 3725e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples, 3726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency, 3727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kNormalSpeech, 3728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kVadUnknown, 3729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 3730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 37356141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 3736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::MixAudioWithFile(AudioFrame& audioFrame, 37379213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int mixingFrequency) 3738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 37392a8df7c375c73a3f477ee5cd9d85336a98f57ee2minyue@webrtc.org assert(mixingFrequency <= 48000); 3740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 374100b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[960]); 3742dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t fileSamples(0); 3743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 37459a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 3748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 3752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We should get the frequency we ask for. 3756d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 3757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 3758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 3759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 3763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 376763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.samples_per_channel_ == fileSamples) 3768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3769d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3770d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 377140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixWithSat(audioFrame.data_, 377240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioFrame.num_channels_, 377340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 377440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1, 377540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples); 3776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3780dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS ") != " 3781dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting "fileSamples(%" PRIuS ")", 378263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, fileSamples); 3783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertInbandDtmfTone() 3791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3792af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Check if we should start a new tone. 3793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfQueue.PendingDtmf() && 3794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !_inbandDtmfGenerator.IsAddingTone() && 3795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.DelaySinceLastTone() > 3796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kMinTelephoneEventSeparationMs) 3797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 37986141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t eventCode(0); 37996141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t lengthMs(0); 38006141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t attenuationDb(0); 3801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); 3803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); 3804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playInbandDtmfEvent) 3805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add tone to output mixer using a reduced length to minimize 3807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // risk of echo. 3808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, 3809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb); 3810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.IsAddingTone()) 3814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 38156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t frequency(0); 3816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.GetSampleRate(frequency); 3817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 381863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (frequency != _audioFrame.sample_rate_hz_) 3819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update sample rate of Dtmf tone since the mixing frequency 3821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has changed. 3822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.SetSampleRate( 38236141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t) (_audioFrame.sample_rate_hz_)); 3824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset the tone to be added taking the new sample rate into 3825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // account. 3826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.ResetTone(); 3827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3828ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 38296141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t toneBuffer[320]; 38306141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t toneSamples(0); 3831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms tone segment and set time since last tone to zero 3832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) 3833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() inserting Dtmf failed"); 3837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3840af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Replace mixed audio with DTMF tone. 3841dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t sample = 0; 384263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org sample < _audioFrame.samples_per_channel_; 3843af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org sample++) 3844af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 3845ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org for (int channel = 0; 3846ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org channel < _audioFrame.num_channels_; 3847af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org channel++) 3848af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 3849dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t index = 3850dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting sample * _audioFrame.num_channels_ + channel; 3851ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.data_[index] = toneBuffer[sample]; 3852af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 3853af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 3854ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 385563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == toneSamples); 3856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 3857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add 10ms to "delay-since-last-tone" counter 3859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.UpdateDelaySinceLastTone(); 3860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38646141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 38654591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgChannel::SendPacketRaw(const void *data, size_t len, bool RTCP) 3866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3867fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 3869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!RTCP) 3873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3874ac547a653862744d0aae560713f8418ad2852085Peter Boström return _transportPtr->SendPacket(data, len); 3875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3878ac547a653862744d0aae560713f8418ad2852085Peter Boström return _transportPtr->SendRTCPPacket(data, len); 3879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3882743758816853df2040a21c5652b0d0e238b1512fdeadbeefvoid Channel::UpdatePlayoutTimestamp(bool rtcp) { 3883743758816853df2040a21c5652b0d0e238b1512fdeadbeef uint32_t playout_timestamp = 0; 3884743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3885743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { 3886743758816853df2040a21c5652b0d0e238b1512fdeadbeef // This can happen if this channel has not been received any RTP packet. In 3887743758816853df2040a21c5652b0d0e238b1512fdeadbeef // this case, NetEq is not capable of computing playout timestamp. 3888743758816853df2040a21c5652b0d0e238b1512fdeadbeef return; 3889743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3890743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3891743758816853df2040a21c5652b0d0e238b1512fdeadbeef uint16_t delay_ms = 0; 3892743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) { 3893743758816853df2040a21c5652b0d0e238b1512fdeadbeef WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3894743758816853df2040a21c5652b0d0e238b1512fdeadbeef "Channel::UpdatePlayoutTimestamp() failed to read playout" 3895743758816853df2040a21c5652b0d0e238b1512fdeadbeef " delay from the ADM"); 3896743758816853df2040a21c5652b0d0e238b1512fdeadbeef _engineStatisticsPtr->SetLastError( 3897743758816853df2040a21c5652b0d0e238b1512fdeadbeef VE_CANNOT_RETRIEVE_VALUE, kTraceError, 3898743758816853df2040a21c5652b0d0e238b1512fdeadbeef "UpdatePlayoutTimestamp() failed to retrieve playout delay"); 3899743758816853df2040a21c5652b0d0e238b1512fdeadbeef return; 3900743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3901743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3902743758816853df2040a21c5652b0d0e238b1512fdeadbeef jitter_buffer_playout_timestamp_ = playout_timestamp; 3903743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3904743758816853df2040a21c5652b0d0e238b1512fdeadbeef // Remove the playout delay. 3905743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000)); 3906743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3907743758816853df2040a21c5652b0d0e238b1512fdeadbeef WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3908743758816853df2040a21c5652b0d0e238b1512fdeadbeef "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu", 3909743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_timestamp); 3910743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3911743758816853df2040a21c5652b0d0e238b1512fdeadbeef { 3912743758816853df2040a21c5652b0d0e238b1512fdeadbeef CriticalSectionScoped cs(video_sync_lock_.get()); 3913743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (rtcp) { 3914743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_timestamp_rtcp_ = playout_timestamp; 3915743758816853df2040a21c5652b0d0e238b1512fdeadbeef } else { 3916743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_timestamp_rtp_ = playout_timestamp; 3917743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3918743758816853df2040a21c5652b0d0e238b1512fdeadbeef playout_delay_ms_ = delay_ms; 3919743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3920743758816853df2040a21c5652b0d0e238b1512fdeadbeef} 3921743758816853df2040a21c5652b0d0e238b1512fdeadbeef 39221de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org// Called for incoming RTP packets after successful RTP header parsing. 39231de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgvoid Channel::UpdatePacketDelay(uint32_t rtp_timestamp, 39241de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t sequence_number) { 39251de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 39261de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 39271de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org rtp_timestamp, sequence_number); 3928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39291de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Get frequency of last received payload 393094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int rtp_receive_frequency = GetPlayoutFrequency(); 3931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3932167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for 3933167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org // every incoming packet. 3934167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org uint32_t timestamp_diff_ms = (rtp_timestamp - 3935167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000); 3936d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) || 3937d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) { 3938d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP 3939d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // timestamp, the resulting difference is negative, but is set to zero. 3940d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // This can happen when a network glitch causes a packet to arrive late, 3941d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // and during long comfort noise periods with clock drift. 3942d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org timestamp_diff_ms = 0; 3943d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org } 3944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39451de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) / 39461de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org (rtp_receive_frequency / 1000); 3947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39481de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _previousTimestamp = rtp_timestamp; 3949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39501de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (timestamp_diff_ms == 0) return; 39511de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 3952743758816853df2040a21c5652b0d0e238b1512fdeadbeef { 3953743758816853df2040a21c5652b0d0e238b1512fdeadbeef CriticalSectionScoped cs(video_sync_lock_.get()); 39541de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 3955743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (packet_delay_ms >= 10 && packet_delay_ms <= 60) { 3956743758816853df2040a21c5652b0d0e238b1512fdeadbeef _recPacketDelayMs = packet_delay_ms; 3957743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 39581de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 3959743758816853df2040a21c5652b0d0e238b1512fdeadbeef if (_average_jitter_buffer_delay_us == 0) { 3960743758816853df2040a21c5652b0d0e238b1512fdeadbeef _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000; 3961743758816853df2040a21c5652b0d0e238b1512fdeadbeef return; 3962743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3963743758816853df2040a21c5652b0d0e238b1512fdeadbeef 3964743758816853df2040a21c5652b0d0e238b1512fdeadbeef // Filter average delay value using exponential filter (alpha is 3965743758816853df2040a21c5652b0d0e238b1512fdeadbeef // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces 3966743758816853df2040a21c5652b0d0e238b1512fdeadbeef // risk of rounding error) and compensate for it in GetDelayEstimate() 3967743758816853df2040a21c5652b0d0e238b1512fdeadbeef // later. 3968743758816853df2040a21c5652b0d0e238b1512fdeadbeef _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 + 3969743758816853df2040a21c5652b0d0e238b1512fdeadbeef 1000 * timestamp_diff_ms + 500) / 8; 3970743758816853df2040a21c5652b0d0e238b1512fdeadbeef } 3971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 3974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterReceiveCodecsToRTPModule() 3975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule()"); 3978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 39816141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 3982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 3984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 3986eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->Codec(idx, &codec) == -1) || 3987822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rtp_receiver_->RegisterReceivePayload( 3988822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 3989822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 3990822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 3991822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 3992822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) == -1)) 3993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 3995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 3996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 3997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() unable" 3999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " to register %s (%d/%d/%d/%d) to RTP/RTCP receiver", 4000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 4001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 4002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 4006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceInfo, 4007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 4008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() %s " 4010fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "(%d/%d/%d/%d) has been added to the RTP/RTCP " 4011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "receiver", 4012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 4013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 4014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40188c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org// Assuming this method is called with valid payload type. 401942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetRedPayloadType(int red_payload_type) { 402042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org CodecInst codec; 402142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org bool found_red = false; 402242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 402342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org // Get default RED settings from the ACM database 402442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org const int num_codecs = AudioCodingModule::NumberOfCodecs(); 402542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org for (int idx = 0; idx < num_codecs; idx++) { 4026eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->Codec(idx, &codec); 402742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!STR_CASE_CMP(codec.plname, "RED")) { 402842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org found_red = true; 402942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org break; 403042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 403142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 403242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 403342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!found_red) { 403442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 403542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 403642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED is not supported"); 403742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 403842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 403942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 40409d532fd2752290e85aa804f29ab9aa6c017c9208turaj@webrtc.org codec.pltype = red_payload_type; 4041eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) < 0) { 404242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 404342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 404442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in ACM module failed"); 404542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 404642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 404742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 404842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) { 404942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 405042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 405142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in RTP/RTCP module failed"); 405242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 405342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 405442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 405542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 405642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 4057ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, 4058ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org unsigned char id) { 4059ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org int error = 0; 4060ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type); 4061ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org if (enable) { 4062ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(type, id); 4063ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org } 4064ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return error; 4065ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org} 4066c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 406794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.orgint32_t Channel::GetPlayoutFrequency() { 406894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int32_t playout_frequency = audio_coding_->PlayoutFrequency(); 406994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org CodecInst current_recive_codec; 407094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (audio_coding_->ReceiveCodec(¤t_recive_codec) == 0) { 407194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (STR_CASE_CMP("G722", current_recive_codec.plname) == 0) { 407294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // Even though the actual sampling rate for G.722 audio is 407394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // 16,000 Hz, the RTP clock rate for the G722 payload format is 407494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // 8,000 Hz because that value was erroneously assigned in 407594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // RFC 1890 and must remain unchanged for backward compatibility. 407694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org playout_frequency = 8000; 407794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } else if (STR_CASE_CMP("opus", current_recive_codec.plname) == 0) { 407894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // We are resampling Opus internally to 32,000 Hz until all our 407994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // DSP routines can operate at 48,000 Hz, but the RTP clock 408094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // rate for the Opus payload format is standardized to 48,000 Hz, 408194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // because that is the maximum supported decoding sampling rate. 408294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org playout_frequency = 48000; 408394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 408494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 408594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org return playout_frequency; 408694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org} 408794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 40882013aeced2b7821a407f302802c4a16fd02728b1Minyueint64_t Channel::GetRTT(bool allow_associate_channel) const { 40892b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 40902b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (method == kRtcpOff) { 40912b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org return 0; 40922b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 40932b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org std::vector<RTCPReportBlock> report_blocks; 40942b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org _rtpRtcpModule->RemoteRTCPStat(&report_blocks); 40952013aeced2b7821a407f302802c4a16fd02728b1Minyue 40962013aeced2b7821a407f302802c4a16fd02728b1Minyue int64_t rtt = 0; 40972b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (report_blocks.empty()) { 40982013aeced2b7821a407f302802c4a16fd02728b1Minyue if (allow_associate_channel) { 40992013aeced2b7821a407f302802c4a16fd02728b1Minyue CriticalSectionScoped lock(assoc_send_channel_lock_.get()); 41002013aeced2b7821a407f302802c4a16fd02728b1Minyue Channel* channel = associate_send_channel_.channel(); 41012013aeced2b7821a407f302802c4a16fd02728b1Minyue // Tries to get RTT from an associated channel. This is important for 41022013aeced2b7821a407f302802c4a16fd02728b1Minyue // receive-only channels. 41032013aeced2b7821a407f302802c4a16fd02728b1Minyue if (channel) { 41042013aeced2b7821a407f302802c4a16fd02728b1Minyue // To prevent infinite recursion and deadlock, calling GetRTT of 41052013aeced2b7821a407f302802c4a16fd02728b1Minyue // associate channel should always use "false" for argument: 41062013aeced2b7821a407f302802c4a16fd02728b1Minyue // |allow_associate_channel|. 41072013aeced2b7821a407f302802c4a16fd02728b1Minyue rtt = channel->GetRTT(false); 41082013aeced2b7821a407f302802c4a16fd02728b1Minyue } 41092013aeced2b7821a407f302802c4a16fd02728b1Minyue } 41102013aeced2b7821a407f302802c4a16fd02728b1Minyue return rtt; 41112b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 41122b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org 41132b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org uint32_t remoteSSRC = rtp_receiver_->SSRC(); 41142b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin(); 41152b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org for (; it != report_blocks.end(); ++it) { 41162b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (it->remoteSSRC == remoteSSRC) 41172b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org break; 41182b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 41192b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (it == report_blocks.end()) { 41202b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // We have not received packets with SSRC matching the report blocks. 41212b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // To calculate RTT we try with the SSRC of the first report block. 41222b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // This is very important for send-only channels where we don't know 41232b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // the SSRC of the other end. 41242b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org remoteSSRC = report_blocks[0].remoteSSRC; 41252b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 41262013aeced2b7821a407f302802c4a16fd02728b1Minyue 412716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t avg_rtt = 0; 412816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t max_rtt= 0; 412916825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t min_rtt = 0; 41302b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) 41312b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org != 0) { 41322b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org return 0; 41332b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 413416825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org return rtt; 41352b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org} 41362b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org 4137d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace voe 4138d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace webrtc 4139