channel.cc revision adf89b7e33cc54dab9365dddead687a46a074cf0
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 134591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include "webrtc/base/format_macros.h" 1494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org#include "webrtc/base/timeutils.h" 15e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org#include "webrtc/common.h" 166388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_device/include/audio_device.h" 176388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/audio_processing/include/audio_processing.h" 18d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 19822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h" 20822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 21822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h" 22822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" 236388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/audio_frame_operations.h" 246388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/process_thread.h" 256388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/modules/utility/interface/rtp_dump.h" 266388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 276388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 286388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 29b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org#include "webrtc/video_engine/include/vie_network.h" 306388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_base.h" 316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_external_media.h" 326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/include/voe_rtp_rtcp.h" 336388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/output_mixer.h" 346388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/statistics.h" 356388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/transmit_mixer.h" 366388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org#include "webrtc/voice_engine/utility.h" 37470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#if defined(_WIN32) 39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <Qos.h> 40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4250419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace webrtc { 4350419b07772de974964072478886c4c35ab9c8ccandrew@webrtc.orgnamespace voe { 44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// Extend the default RTCP statistics struct with max_jitter, defined as the 4654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// maximum jitter value seen in an RTCP report block. 4754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.orgstruct ChannelStatistics : public RtcpStatistics { 4854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics() : rtcp(), max_jitter(0) {} 4954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 5054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics rtcp; 5154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org uint32_t max_jitter; 5254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org}; 5354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 5454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org// Statistics callback, called at each generation of a new RTCP report block. 5554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.orgclass StatisticsProxy : public RtcpStatisticsCallback { 5654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org public: 5754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org StatisticsProxy(uint32_t ssrc) 5854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org : stats_lock_(CriticalSectionWrapper::CreateCriticalSection()), 5954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ssrc_(ssrc) {} 6054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org virtual ~StatisticsProxy() {} 6154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 6214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void StatisticsUpdated(const RtcpStatistics& statistics, 6314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org uint32_t ssrc) override { 6454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (ssrc != ssrc_) 6554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org return; 6654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 6754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org CriticalSectionScoped cs(stats_lock_.get()); 6854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_.rtcp = statistics; 6954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (statistics.jitter > stats_.max_jitter) { 7054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_.max_jitter = statistics.jitter; 7154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 7254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 7354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 7414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void CNameChanged(const char* cname, uint32_t ssrc) override {} 75ce4e9a356200170abcdd44ff2af95f87a6781b8epbos@webrtc.org 7654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org void ResetStatistics() { 7754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org CriticalSectionScoped cs(stats_lock_.get()); 7854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_ = ChannelStatistics(); 7954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 8054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 8154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics GetStats() { 8254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org CriticalSectionScoped cs(stats_lock_.get()); 8354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org return stats_; 8454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 8554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 8654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org private: 8754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // StatisticsUpdated calls are triggered from threads in the RTP module, 8854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // while GetStats calls can be triggered from the public voice engine API, 8954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // hence synchronization is needed. 9000b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<CriticalSectionWrapper> stats_lock_; 9154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org const uint32_t ssrc_; 9254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics stats_; 9354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org}; 9454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 950a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.orgclass VoERtcpObserver : public RtcpBandwidthObserver { 96c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org public: 970a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org explicit VoERtcpObserver(Channel* owner) : owner_(owner) {} 980a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org virtual ~VoERtcpObserver() {} 990a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1000a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org void OnReceivedEstimatedBitrate(uint32_t bitrate) override { 1010a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Not used for Voice Engine. 1020a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1030a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 10414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks, 10514665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int64_t rtt, 10614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int64_t now_ms) override { 1070a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // TODO(mflodman): Do we need to aggregate reports here or can we jut send 1080a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // what we get? I.e. do we ever get multiple reports bundled into one RTCP 1090a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // report for VoiceEngine? 1100a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (report_blocks.empty()) 1110a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org return; 1120a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1130a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int fraction_lost_aggregate = 0; 1140a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int total_number_of_packets = 0; 1150a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1160a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // If receiving multiple report blocks, calculate the weighted average based 1170a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // on the number of packets a report refers to. 1180a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org for (ReportBlockList::const_iterator block_it = report_blocks.begin(); 1190a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org block_it != report_blocks.end(); ++block_it) { 1200a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Find the previous extended high sequence number for this remote SSRC, 1210a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // to calculate the number of RTP packets this report refers to. Ignore if 1220a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // we haven't seen this SSRC before. 1230a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org std::map<uint32_t, uint32_t>::iterator seq_num_it = 1240a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org extended_max_sequence_number_.find(block_it->sourceSSRC); 1250a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int number_of_packets = 0; 1260a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (seq_num_it != extended_max_sequence_number_.end()) { 1270a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org number_of_packets = block_it->extendedHighSeqNum - seq_num_it->second; 1280a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1290a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org fraction_lost_aggregate += number_of_packets * block_it->fractionLost; 1300a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org total_number_of_packets += number_of_packets; 1310a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1320a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org extended_max_sequence_number_[block_it->sourceSSRC] = 1330a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org block_it->extendedHighSeqNum; 1340a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1350a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org int weighted_fraction_lost = 0; 1360a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (total_number_of_packets > 0) { 1370a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org weighted_fraction_lost = (fraction_lost_aggregate + 1380a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org total_number_of_packets / 2) / total_number_of_packets; 1390a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org } 1400a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org owner_->OnIncomingFractionLoss(weighted_fraction_lost); 141c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 142c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 143c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org private: 144c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org Channel* owner_; 1450a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org // Maps remote side ssrc to extended highest sequence number received. 1460a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org std::map<uint32_t, uint32_t> extended_max_sequence_number_; 147c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org}; 148c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 1496141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SendData(FrameType frameType, 1516141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t payloadType, 1526141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t timeStamp, 1536141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t* payloadData, 1544591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payloadSize, 155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const RTPFragmentationHeader* fragmentation) 156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u," 1594591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org " payloadSize=%" PRIuS ", fragmentation=0x%x)", 1604591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org frameType, payloadType, timeStamp, 1614591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org payloadSize, fragmentation); 162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_includeAudioLevelIndication) 164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store current audio level in the RTP/RTCP module. 166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The level will be used in combination with voice-activity state 167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // (frameType) to add an RTP header extension 168382c0c209d323c1e6972d988a7b26f08fc2e8a6bandrew@webrtc.org _rtpRtcpModule->SetAudioLevel(rms_level_.RMS()); 169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push data from ACM to RTP/RTCP-module to deliver audio frame for 172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packetization. 173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This call will trigger Transport::SendPacket() from the RTP/RTCP module. 1742853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType, 175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadType, 176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timeStamp, 177ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // Leaving the time when this frame was 178ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // received from the capture device as 179ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org // undefined for voice for now. 180ddfdfed3b55de3da5fda9a55d34e46d6e422baafstefan@webrtc.org -1, 181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadData, 182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fragmentation) == -1) 184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendData() failed to send data to RTP/RTCP module"); 188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp = timeStamp; 192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType = payloadType; 193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 198e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.orgChannel::InFrameType(FrameType frame_type) 199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 201e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.org "Channel::InFrameType(frame_type=%d)", frame_type); 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2039a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 204e9217b4bdbf9a8fd8b4882b2f995665927f28ad2henrik.lundin@webrtc.org _sendFrameType = (frame_type == kAudioFrameSpeech); 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2086141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 2099213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnRxVadDetected(int vadDecision) 210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnRxVadDetected(vadDecision=%d)", vadDecision); 213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2149a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr->OnRxVad(_channelId, vadDecision); 218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2244591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgChannel::SendPacket(int channel, const void *data, size_t len) 225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2304591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "Channel::SendPacket(channel=%d, len=%" PRIuS ")", channel, 2314591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org len); 232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 233fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 234fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org 235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() failed to send RTP packet due to" 239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " invalid transport object"); 240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2436141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 2444591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bufferLength = len; 245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTP packet to a file (if RTP dump is enabled). 2476141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpOut.DumpPacket((const uint8_t*)data, len) == -1) 248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTP dump to output file failed"); 252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 254fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org int n = _transportPtr->SendPacket(channel, bufferToSendPtr, 255fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org bufferLength); 256fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (n < 0) { 257fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org std::string transport_name = 258fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org _externalTransport ? "external transport" : "WebRtc sockets"; 259fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 260fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 261fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendPacket() RTP transmission using %s failed", 262fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org transport_name.c_str()); 263fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 265fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return n; 266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2694591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgChannel::SendRTCPPacket(int channel, const void *data, size_t len) 270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channel = VoEChannelId(channel); 272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(channel == _channelId); 273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2754591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "Channel::SendRTCPPacket(channel=%d, len=%" PRIuS ")", channel, 2764591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org len); 277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 278fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 279fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (_transportPtr == NULL) 280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 281fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVoice, 282fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 283fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendRTCPPacket() failed to send RTCP packet" 284fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org " due to invalid transport object"); 285fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t* bufferToSendPtr = (uint8_t*)data; 2894591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bufferLength = len; 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dump the RTCP packet to a file (if RTP dump is enabled). 2926141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpOut.DumpPacket((const uint8_t*)data, len) == -1) 293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendPacket() RTCP dump to output file failed"); 297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 299fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org int n = _transportPtr->SendRTCPPacket(channel, 300fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org bufferToSendPtr, 301fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org bufferLength); 302fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org if (n < 0) { 303fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org std::string transport_name = 304fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org _externalTransport ? "external transport" : "WebRtc sockets"; 305fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, 306fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org VoEId(_instanceId,_channelId), 307fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org "Channel::SendRTCPPacket() transmission using %s failed", 308fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org transport_name.c_str()); 309fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return -1; 310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 311fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org return n; 312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 3159213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::OnPlayTelephoneEvent(int32_t id, 3169213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t event, 3179213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint16_t lengthMs, 3189213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t volume) 319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnPlayTelephoneEvent(id=%d, event=%u, lengthMs=%u," 322fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " volume=%u)", id, event, lengthMs, volume); 323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_playOutbandDtmfEvent || (event > 15)) 325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ignore callback since feedback is disabled or event is not a 327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Dtmf tone event. 328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return; 329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(_outputMixerPtr != NULL); 332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Start playing out the Dtmf tone (if playout is enabled). 334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reduce length of tone with 80ms to the reduce risk of echo. 335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume); 336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 339286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgChannel::OnIncomingSSRCChanged(int32_t id, uint32_t ssrc) 340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingSSRCChanged(id=%d, SSRC=%d)", 343286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org id, ssrc); 344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 345b295a3f5920e2706d42c960c5180c7cc6e1f435edwkang@webrtc.org // Update ssrc so that NTP for AV sync can be updated. 346b295a3f5920e2706d42c960c5180c7cc6e1f435edwkang@webrtc.org _rtpRtcpModule->SetRemoteSSRC(ssrc); 347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3499213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgvoid Channel::OnIncomingCSRCChanged(int32_t id, 3509213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t CSRC, 3519213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool added) 352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnIncomingCSRCChanged(id=%d, CSRC=%d, added=%d)", 355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, CSRC, added); 356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 358286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgvoid Channel::ResetStatistics(uint32_t ssrc) { 359286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician* statistician = 360286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtp_receive_statistics_->GetStatistician(ssrc); 361286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (statistician) { 362286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->ResetStatistics(); 363286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 36454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistics_proxy_->ResetStatistics(); 365822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 366822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 3676141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::OnInitializeDecoder( 3699213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int32_t id, 3709213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int8_t payloadType, 371813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org const char payloadName[RTP_PAYLOAD_NAME_SIZE], 3729213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int frequency, 3739213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint8_t channels, 3749213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org uint32_t rate) 375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder(id=%d, payloadType=%d, " 378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "payloadName=%s, frequency=%u, channels=%u, rate=%u)", 379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, payloadType, payloadName, frequency, channels, rate); 380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 381ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org assert(VoEChannelId(id) == _channelId); 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 383f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst receiveCodec = {0}; 384f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org CodecInst dummyCodec = {0}; 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pltype = payloadType; 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.plfreq = frequency; 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.channels = channels; 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.rate = rate; 390f75901fa4c5f9a1bcefc265b98a480c72119650chenrika@webrtc.org strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); 391ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 392eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels); 393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com receiveCodec.pacsize = dummyCodec.pacsize; 394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register the new codec to the ACM 396eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(receiveCodec) == -1) 397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 399ceb148ce593627ed0d30a1a8c01752bdebf9172dandrew@webrtc.org VoEId(_instanceId, _channelId), 400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnInitializeDecoder() invalid codec (" 401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "pt=%d, name=%s) received - 1", payloadType, payloadName); 402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR); 403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4096141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 4106141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::OnReceivedPayloadData(const uint8_t* payloadData, 4114591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payloadSize, 412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const WebRtcRTPHeader* rtpHeader) 413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 4154591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS "," 416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " payloadType=%u, audioChannel=%u)", 417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com payloadSize, 418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.payloadType, 419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->type.Audio.channel); 420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 421944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing) 422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid inserting into NetEQ when we are not playing. Count the 424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // packet as discarded. 425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, 426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "received packet is discarded since playing is not" 428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " activated"); 429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets++; 430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Push the incoming payload (parsed and ready for decoding) into the ACM 434eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->IncomingPacket(payloadData, 435eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org payloadSize, 436eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org *rtpHeader) != 0) 437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning, 440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::OnReceivedPayloadData() unable to push data to the ACM"); 441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 444d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org // Update the packet delay. 445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdatePacketDelay(rtpHeader->header.timestamp, 446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpHeader->header.sequenceNumber); 447d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org 44816825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t round_trip_time = 0; 449822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, 450822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org NULL, NULL, NULL); 451822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 452eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org std::vector<uint16_t> nack_list = audio_coding_->GetNackList( 453822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org round_trip_time); 454822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!nack_list.empty()) { 455822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // Can't use nack_list.data() since it's not supported by all 456822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // compilers. 457822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size())); 458d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org } 459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4627bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::OnRecoveredPacket(const uint8_t* rtp_packet, 4634591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t rtp_packet_length) { 4647bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org RTPHeader header; 4657bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) { 4667bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVoice, _channelId, 4677bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "IncomingPacket invalid RTP header"); 4687bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4697bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 4707bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org header.payload_type_frequency = 4717bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); 4727bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (header.payload_type_frequency < 0) 4737bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 4747bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ReceivePacket(rtp_packet, rtp_packet_length, header, false); 4757bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 4767bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 4779213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgint32_t Channel::GetAudioFrame(int32_t id, AudioFrame& audioFrame) 478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame(id=%d)", id); 481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms raw PCM data from the ACM (mixer limits output frequency) 483eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->PlayoutData10Ms(audioFrame.sample_rate_hz_, 484eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org &audioFrame) == -1) 485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetAudioFrame() PlayoutData10Ms() failed!"); 4897859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // In all likelihood, the audio in this frame is garbage. We return an 4907859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // error so that the audio mixer module doesn't add it to the mix. As 4917859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // a result, it won't be played out and the actions skipped here are 4927859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org // irrelevant. 4937859e109855b9536593892734aa65af974e6baa4andrew@webrtc.org return -1; 494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_RxVadDetection) 497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com UpdateRxVadDetection(audioFrame); 499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Convert module ID to internal VoE channel ID 50263a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.id_ = VoEChannelId(audioFrame.id_); 503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Store speech type for dead-or-alive detection 50463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _outputSpeechType = audioFrame.speech_type_; 505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 506944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org ChannelState::State state = channel_state_.Get(); 507944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 508944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (state.rx_apm_is_enabled) { 50960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org int err = rx_audioproc_->ProcessStream(&audioFrame); 51060730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org if (err) { 51160730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org LOG(LS_ERROR) << "ProcessStream() error: " << err; 51260730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org assert(false); 51360730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org } 514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 51663420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float output_gain = 1.0f; 51763420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float left_pan = 1.0f; 51863420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org float right_pan = 1.0f; 51963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org { 52063420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 52163420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org output_gain = _outputGain; 52263420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org left_pan = _panLeft; 52363420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org right_pan= _panRight; 52463420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org } 52563420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Output volume scaling 52763420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org if (output_gain < 0.99f || output_gain > 1.01f) 528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 52963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org AudioFrameOperations::ScaleWithSat(output_gain, audioFrame); 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Scale left and/or right channel(s) if stereo and master balance is 533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // active 534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 53563420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org if (left_pan != 1.0f || right_pan != 1.0f) 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 53763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.num_channels_ == 1) 538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Emulate stereo mode since panning is active. 540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The mono signal is copied to both left and right channels here. 5414ecea3e1057eebf846af9b93abf8faf8571bc576andrew@webrtc.org AudioFrameOperations::MonoToStereo(&audioFrame); 542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // For true stereo mode (when we are receiving a stereo signal), no 544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // action is needed. 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Do the panning operation (the audio frame contains stereo at this 547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // stage) 54863420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org AudioFrameOperations::Scale(left_pan, right_pan, audioFrame); 549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Mix decoded PCM output with file if file mixing is enabled 552944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (state.output_file_playing) 553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 55463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org MixAudioWithFile(audioFrame, audioFrame.sample_rate_hz_); 555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // External media 558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5609a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 56163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (audioFrame.num_channels_ == 2); 562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr->Process( 565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kPlaybackPerChannel, 5676141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (int16_t*)audioFrame.data_, 56863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, 56963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.sample_rate_hz_, 570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Record playout if enabled 575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5769a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording && _outputFileRecorderPtr) 579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 5805398d9583b713f83db843a15f8bcc2ef8df23bccniklas.enbom@webrtc.org _outputFileRecorderPtr->RecordAudioToFile(audioFrame); 581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Measure audio level (0-9) 585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.ComputeLevel(audioFrame); 586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 58794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (capture_start_rtp_time_stamp_ < 0 && audioFrame.timestamp_ != 0) { 58894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // The first frame with a valid rtp timestamp. 589cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org capture_start_rtp_time_stamp_ = audioFrame.timestamp_; 59094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 59194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 59294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (capture_start_rtp_time_stamp_ >= 0) { 59394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // audioFrame.timestamp_ should be valid from now on. 59494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 59594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // Compute elapsed time. 59694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int64_t unwrap_timestamp = 59794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org rtp_ts_wraparound_handler_->Unwrap(audioFrame.timestamp_); 59894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org audioFrame.elapsed_time_ms_ = 59994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org (unwrap_timestamp - capture_start_rtp_time_stamp_) / 60094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org (GetPlayoutFrequency() / 1000); 60194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 6028e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org { 603cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 6048e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // Compute ntp time. 6058e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org audioFrame.ntp_time_ms_ = ntp_estimator_.Estimate( 6068e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org audioFrame.timestamp_); 6078e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received. 6088e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org if (audioFrame.ntp_time_ms_ > 0) { 6098e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // Compute |capture_start_ntp_time_ms_| so that 6108e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_| 6118e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org capture_start_ntp_time_ms_ = 6128e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org audioFrame.ntp_time_ms_ - audioFrame.elapsed_time_ms_; 6138e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org } 614cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 615cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 616cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org 617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6206141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 6219213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::NeededFrequency(int32_t id) 622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::NeededFrequency(id=%d)", id); 625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int highestNeeded = 0; 627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Determine highest needed receive frequency 629eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org int32_t receiveFrequency = audio_coding_->ReceiveFrequency(); 630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Return the bigger of playout and receive frequency in the ACM. 632eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->PlayoutFrequency() > receiveFrequency) 633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 634eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org highestNeeded = audio_coding_->PlayoutFrequency(); 635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded = receiveFrequency; 639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Special case, if we're playing a file on the playout side 642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // we take that frequency into consideration as well 643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This is not needed on sending side, since the codec will 644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // limit the spectrum anyway. 645944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 6479a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 648944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (_outputFilePlayerPtr) 649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(_outputFilePlayerPtr->Frequency()>highestNeeded) 651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com highestNeeded=_outputFilePlayerPtr->Frequency(); 653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(highestNeeded); 658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 6606141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::CreateChannel(Channel*& channel, 6629213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int32_t channelId, 663e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org uint32_t instanceId, 664e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org const Config& config) 665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId), 667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel(channelId=%d, instanceId=%d)", 668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com channelId, instanceId); 669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 670e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org channel = new Channel(channelId, instanceId, config); 671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (channel == NULL) 672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, 674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(instanceId,channelId), 675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::CreateChannel() unable to allocate memory for" 676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " channel"); 677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6839213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayNotification(int32_t id, uint32_t durationMs) 684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayNotification(id=%d, durationMs=%d)", 687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 6939213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordNotification(int32_t id, uint32_t durationMs) 694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordNotification(id=%d, durationMs=%d)", 697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com id, durationMs); 698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Not implement yet 700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 7039213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::PlayFileEnded(int32_t id) 704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded(id=%d)", id); 707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (id == _inputFilePlayerId) 709470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 710944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(false); 711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => input file player module is" 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (id == _outputFilePlayerId) 717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 718944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PlayFileEnded() => output file player module is" 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 723470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 7279213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::RecordFileEnded(int32_t id) 728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded(id=%d)", id); 731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(id == _outputFileRecorderId); 733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7349a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RecordFileEnded() => output file recorder module is" 740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " shutdown"); 741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7439213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::Channel(int32_t channelId, 744e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org uint32_t instanceId, 745e509f943eded156f7a8365b0b001abe73646acfaminyue@webrtc.org const Config& config) : 746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), 74863420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org volume_settings_critsect_(*CriticalSectionWrapper::CreateCriticalSection()), 749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _instanceId(instanceId), 75022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _channelId(channelId), 751a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org rtp_header_parser_(RtpHeaderParser::Create()), 752822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_( 753dc80bae2a62a1bdbe0d342b3260a7e5b2cb958dfandresp@webrtc.org new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true))), 754822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receive_statistics_(ReceiveStatistics::Create( 755822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org Clock::GetRealTimeClock())), 756822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receiver_(RtpReceiver::CreateAudioReceiver( 757822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org VoEModuleId(instanceId, channelId), Clock::GetRealTimeClock(), this, 758822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org this, this, rtp_payload_registry_.get())), 759822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()), 76034fe0153b90c3e616a0fd5aba8aa8118ae600760henrik.lundin@webrtc.org audio_coding_(AudioCodingModule::Create( 76122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com VoEModuleId(instanceId, channelId))), 762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpIn(*RtpDump::CreateRtpDump()), 763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rtpDumpOut(*RtpDump::CreateRtpDump()), 764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel(), 765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport(false), 766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr(NULL), 767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr(NULL), 768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr(NULL), 769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Avoid conflict with other channels by adding 1024 - 1026, 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // won't use as much as 1024 channels. 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024), 772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025), 773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026), 774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording(false), 77522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfQueue(VoEModuleId(instanceId, channelId)), 77622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)), 77722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _outputExternalMedia(false), 778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr(NULL), 779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr(NULL), 78022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _timeStamp(0), // This is just an offset, RTP module will add it's own random offset 78122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendTelephoneEventPayloadType(106), 7828e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org ntp_estimator_(Clock::GetRealTimeClock()), 783167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org jitter_buffer_playout_timestamp_(0), 7841de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtp_(0), 7851de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_(0), 78654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org playout_delay_ms_(0), 78722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _numberOfDiscardedPackets(0), 78809e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org send_sequence_number_(0), 789cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org ts_stats_lock_(CriticalSectionWrapper::CreateCriticalSection()), 79094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()), 79194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org capture_start_rtp_time_stamp_(-1), 792cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org capture_start_ntp_time_ms_(-1), 79322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _engineStatisticsPtr(NULL), 7942919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _outputMixerPtr(NULL), 7952919e95c2a59a087ba8297c2f551c3ebc3754c9ehenrika@webrtc.org _transmitMixerPtr(NULL), 79622963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _moduleProcessThreadPtr(NULL), 79722963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _audioDeviceModulePtr(NULL), 79822963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _voiceEngineObserverPtr(NULL), 79922963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _callbackCritSectPtr(NULL), 80022963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _transportPtr(NULL), 80122963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _rxVadObserverPtr(NULL), 80222963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _oldVadDecision(-1), 80322963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _sendFrameType(0), 8041b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing(false), 80522963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _mixFileWithMicrophone(false), 806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute(false), 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft(1.0f), 808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight(1.0f), 809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain(1.0f), 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent(false), 811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent(false), 812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastLocalTimeStamp(0), 813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _lastPayloadType(0), 81422963abffe4179e75f18a2e7be1d1c58c9518089xians@google.com _includeAudioLevelIndication(false), 815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputSpeechType(AudioFrame::kNormalSpeech), 816b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_(NULL), 817b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org video_channel_(-1), 8181de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us(0), 819e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org least_required_delay_ms_(0), 820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _previousTimestamp(0), 821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _recPacketDelayMs(20), 822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection(false), 823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled(false), 8247bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org _rxNsIsEnabled(false), 825c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org restored_packet_in_use_(false), 8260a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org rtcp_observer_(new VoERtcpObserver(this)), 82774aaf29a0ff1b211dbfdbb6309791111a7871779minyue@webrtc.org network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())) 828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Channel() - ctor"); 831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.ResetDtmf(); 832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.Init(); 833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 8352853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RtpRtcp::Configuration configuration; 8362853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.id = VoEModuleId(instanceId, channelId); 8372853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio = true; 8382853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.outgoing_transport = this; 8392853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org configuration.audio_messages = this; 840822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org configuration.receive_statistics = rtp_receive_statistics_.get(); 8410a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org configuration.bandwidth_callback = rtcp_observer_.get(); 8422853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org 8432853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration)); 84454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 84554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC())); 84654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->RegisterRtcpStatisticsCallback( 84754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistics_proxy_.get()); 848f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org 849f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org Config audioproc_config; 850f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false)); 851f927fd64812b4a42a0f4e2686683a43d74b4bf08aluebs@webrtc.org rx_audioproc_.reset(AudioProcessing::Create(audioproc_config)); 852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::~Channel() 855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 85654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL); 857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId), 858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::~Channel() - dtor"); 859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMedia) 861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kPlaybackPerChannel); 863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 864944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_external_media) 865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com DeRegisterExternalMediaProcessing(kRecordingPerChannel); 867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopSend(); 869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com StopPlayout(); 870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 8729a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr) 881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr->StopPlayingFile(); 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFilePlayerPtr = NULL; 886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The order to safely shutdown modules in a channel is: 897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 1. De-register callbacks in modules 898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 2. De-register modules in process thread 899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // 3. Destroy modules 900eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterTransportCallback(NULL) == -1) 901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register transport callback" 905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 907eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterVADCallback(NULL) == -1) 908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "~Channel() failed to de-register VAD callback" 912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " (Audio coding module)"); 913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register modules in process thread 9153985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); 9163985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org 917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // End of modules shutdown 918470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Delete other objects 920b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (vie_network_) { 921b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_->Release(); 922b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_ = NULL; 923b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpIn); 925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump::DestroyRtpDump(&_rtpDumpOut); 926470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_callbackCritSect; 927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete &_fileCritSect; 92863420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org delete &volume_settings_critsect_; 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9316141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Init() 933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init()"); 936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 937944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.Reset(); 938944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Initial sanity 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((_engineStatisticsPtr == NULL) || 942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (_moduleProcessThreadPtr == NULL)) 943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, 945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() must call SetEngineInformation() first"); 947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add modules to process thread (for periodic schedulation) 951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9523985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()); 9533985f0151aff9b91418733795a98140079c19a73tommi@webrtc.org 954c450a1966965fbb3c16ec6d02c3d5cbec67df500pwestin@webrtc.org // --- ACM initialization 955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 95645c6449114ab69cab755410f69567fa7e20f8106Henrik Lundin if ((audio_coding_->InitializeReceiver() == -1) 957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_AVT 958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // out-of-band Dtmf tones are played out by default 95945c6449114ab69cab755410f69567fa7e20f8106Henrik Lundin || (audio_coding_->SetDtmfPlayoutStatus(true) == -1) 960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 96145c6449114ab69cab755410f69567fa7e20f8106Henrik Lundin ) 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to initialize the ACM - 1"); 966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- RTP/RTCP module initialization 970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that RTCP is enabled by default for the created channel. 972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Note that, the module will keep generating RTCP until it is explicitly 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // disabled by the user. 974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // After StopListen (when no sockets exists), RTCP packets will no longer 975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // be transmitted since the Transport object will then be invalid. 976822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org telephone_event_handler_->SetTelephoneEventForwardToDecoder(true); 977822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org // RTCP is enabled by default. 978d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetRTCPStatus(kRtcpCompound); 979d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org // --- Register all permanent callbacks 980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const bool fail = 981eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterTransportCallback(this) == -1) || 982eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterVADCallback(this) == -1); 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fail) 985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_INIT_CHANNEL, kTraceError, 988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() callbacks not registered"); 989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Register all supported codecs to the receiving side of the 993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // RTP/RTCP module 994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 9966141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 1001eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->Codec(idx, &codec) == -1) || 1002822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rtp_receiver_->RegisterReceivePayload( 1003822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1004822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 1005822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1006822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1007822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) == -1)) 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() unable to register %s (%d/%d/%d/%d) " 1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "to RTP/RTCP receiver", 1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() %s (%d/%d/%d/%d) has been added to " 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "the RTP/RTCP receiver", 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Ensure that PCMU is used as default codec on the sending side 10274517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) 1028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com SetSendCodec(codec); 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register default PT for outband 'telephone-event' 1033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "telephone-event")) 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 10352853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) || 1036eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterReceiveCodec(codec) == -1)) 1037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register outband " 1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "'telephone-event' (%d/%d) correctly", 1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "CN")) 1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1048eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->RegisterSendCodec(codec) == -1) || 1049eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org (audio_coding_->RegisterReceiveCodec(codec) == -1) || 10502853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org (_rtpRtcpModule->RegisterSendPayload(codec) == -1)) 1051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register CN (%d/%d) " 1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly - 1", 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_CODEC_RED 1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Register RED to the receiving side of the ACM. 1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We will not receive an OnInitializeDecoder() callback for RED. 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!STR_CASE_CMP(codec.plname, "RED")) 1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1064eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) == -1) 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::Init() failed to register RED (%d/%d) " 1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "correctly", 1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype, codec.plfreq); 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1075684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 10766c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org if (rx_audioproc_->noise_suppression()->set_level(kDefaultNsMode) != 0) { 10776c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org LOG_FERR1(LS_ERROR, noise_suppression()->set_level, kDefaultNsMode); 10786c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org return -1; 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 10806c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org if (rx_audioproc_->gain_control()->set_mode(kDefaultRxAgcMode) != 0) { 10816c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org LOG_FERR1(LS_ERROR, gain_control()->set_mode, kDefaultRxAgcMode); 10826c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org return -1; 1083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetEngineInformation(Statistics& engineStatistics, 1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OutputMixer& outputMixer, 1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com voe::TransmitMixer& transmitMixer, 1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessThread& moduleProcessThread, 1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioDeviceModule& audioDeviceModule, 1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoiceEngineObserver* voiceEngineObserver, 1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CriticalSectionWrapper* callbackCritSect) 1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetEngineInformation()"); 1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr = &engineStatistics; 1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr = &outputMixer; 1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transmitMixerPtr = &transmitMixer, 1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _moduleProcessThreadPtr = &moduleProcessThread; 1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioDeviceModulePtr = &audioDeviceModule; 1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = voiceEngineObserver; 1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _callbackCritSectPtr = callbackCritSect; 1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11096141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateLocalTimeStamp() 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 111363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11176141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartPlayout() 1119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayout()"); 1122944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 1123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 11261b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 11271b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 11281b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Add participant as candidates for mixing. 11291b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) 11301b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 11311b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 11321b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 11331b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StartPlayout() failed to add participant to mixer"); 11341b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 11351b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1138944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetPlaying(true); 1139ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1140ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 1141ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11456141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopPlayout() 1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayout()"); 1150944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing) 1151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 11541b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 11551b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (!_externalMixing) { 11561b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com // Remove participant as candidates for mixing 11571b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) 11581b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 11591b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 11601b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 11611b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "StopPlayout() failed to remove participant from mixer"); 11621b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 11631b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1166944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetPlaying(false); 1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputAudioLevel.Clear(); 1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 11726141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartSend() 1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartSend()"); 117709e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // Resume the previous sequence number which was reset by StopSend(). 1178944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org // This needs to be done before |sending| is set to true. 117909e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org if (send_sequence_number_) 118009e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org SetInitSequenceNumber(send_sequence_number_); 118109e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org 1182944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().sending) 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1184944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return 0; 1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1186944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(true); 1187e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 11882853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(true) != 0) 1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to start sending"); 11939a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1194944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(false); 1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1197e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12016141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopSend() 1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopSend()"); 1206944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().sending) 1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1208944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return 0; 1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1210944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetSending(false); 1211e07247af8d0888529e14156a9929cbd2376f8442xians@webrtc.org 121209e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // Store the sequence number to be able to pick up the same sequence for 121309e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // the next StartSend(). This is needed for restarting device, otherwise 121409e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // it might cause libSRTP to complain about packets being replayed. 121509e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring 121609e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // CL is landed. See issue 121709e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org // https://code.google.com/p/webrtc/issues/detail?id=2111 . 121809e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org send_sequence_number_ = _rtpRtcpModule->SequenceNumber(); 121909e8c47ee5c58e5e86b09dc1950f8d3f9f24cd9fxians@webrtc.org 1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset sending SSRC and sequence number and triggers direct transmission 1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // of RTCP BYE 12222853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetSendingStatus(false) == -1 || 12232853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->ResetSendDataCountersRTP() == -1) 1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartSend() RTP/RTCP failed to stop sending"); 1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12336141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartReceiving() 1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartReceiving()"); 1238944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().receiving) 1239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1242944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetReceiving(true); 1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _numberOfDiscardedPackets = 0; 1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12476141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopReceiving() 1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopReceiving()"); 1252944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().receiving) 1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1256684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1257944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetReceiving(false); 1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12616141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) 1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterVoiceEngineObserver()"); 12669a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_voiceEngineObserverPtr) 1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 1272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterVoiceEngineObserver() observer already enabled"); 1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = &observer; 1276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12796141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterVoiceEngineObserver() 1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterVoiceEngineObserver()"); 12849a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_voiceEngineObserverPtr) 1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterVoiceEngineObserver() observer already disabled"); 1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _voiceEngineObserverPtr = NULL; 1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 12976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendCodec(CodecInst& codec) 1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1300eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org return (audio_coding_->SendCodec(&codec)); 1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13036141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecCodec(CodecInst& codec) 1305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1306eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org return (audio_coding_->ReceiveCodec(&codec)); 1307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13096141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCodec(const CodecInst& codec) 1311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCodec()"); 1314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1315eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) != 0) 1316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to ACM"); 1319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13222853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 13242853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 13252853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to register codec to" 1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " RTP/RTCP module"); 1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13352853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0) 1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCodec() failed to set audio packet size"); 1339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1345adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusenvoid Channel::SetBitRate(int bitrate_bps) { 1346adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1347adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen "Channel::SetBitRate(bitrate_bps=%d)", bitrate_bps); 1348adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen audio_coding_->SetBitRate(bitrate_bps); 1349adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen} 1350adf89b7e33cc54dab9365dddead687a46a074cf0Ivo Creusen 13510a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.orgvoid Channel::OnIncomingFractionLoss(int fraction_lost) { 135274aaf29a0ff1b211dbfdbb6309791111a7871779minyue@webrtc.org network_predictor_->UpdatePacketLossRate(fraction_lost); 13530a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org uint8_t average_fraction_loss = network_predictor_->GetLossRate(); 13540a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 1355c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org // Normalizes rate to 0 - 100. 13560a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org if (audio_coding_->SetPacketLossRate( 13570a7d4eed98ccec0c2b3e7522e7b2dde1919a4ae3mflodman@webrtc.org 100 * average_fraction_loss / 255) != 0) { 1358c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org assert(false); // This should not happen. 1359c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 1360c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 1361c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 13626141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX) 1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetVADStatus(mode=%d)", mode); 1367664ccb7d8da3adfffdb7c56f885b633224555e6ehenrik.lundin@webrtc.org assert(!(disableDTX && enableVAD)); // disableDTX mode is deprecated. 1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // To disable VAD, DTX must be disabled too 1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disableDTX = ((enableVAD == false) ? true : disableDTX); 1370eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetVAD(!disableDTX, enableVAD, mode) != 0) 1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetVADStatus() failed to set VAD"); 1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13806141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX) 1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetVADStatus"); 1385eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->VAD(&disabledDTX, &enabledVAD, &mode) != 0) 1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetVADStatus() failed to get VAD status"); 1390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com disabledDTX = !disabledDTX; 1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 13966141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRecPayloadType(const CodecInst& codec) 1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRecPayloadType()"); 1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1402944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while playing"); 1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1409944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().receiving) 1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_LISTENING, kTraceError, 1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() unable to set PT while listening"); 1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codec.pltype == -1) 1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // De-register the selected codec (RTP/RTCP module and ACM) 1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14216141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t pltype(-1); 1422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst rxCodec = codec; 1423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get payload type for the given codec 1425822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_->ReceivePayloadType( 1426822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.plname, 1427822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.plfreq, 1428822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rxCodec.channels, 1429822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rxCodec.rate < 0) ? 0 : rxCodec.rate, 1430822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &pltype); 1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rxCodec.pltype = pltype; 1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1433822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0) 1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, 1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module deregistration " 1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1442eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0) 1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM deregistration failed - 1"); 1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1452822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->RegisterReceivePayload( 1453822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1454822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 1455822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1456822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1457822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) != 0) 1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // First attempt to register failed => de-register and try again 1460822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_receiver_->DeRegisterReceivePayload(codec.pltype); 1461822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_receiver_->RegisterReceivePayload( 1462822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1463822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 1464822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1465822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1466822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) != 0) 1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() RTP/RTCP-module registration failed"); 1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1474eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) != 0) 1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1476eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->UnregisterReceiveCodec(codec.pltype); 1477eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterReceiveCodec(codec) != 0) 1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRecPayloadType() ACM registration failed - 1"); 1482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 14886141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRecPayloadType(CodecInst& codec) 1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRecPayloadType()"); 14936141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(-1); 1494822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (rtp_payload_registry_->ReceivePayloadType( 1495822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 1496822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 1497822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 1498822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate, 1499822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &payloadType) != 0) 1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 150237198007eab6731fa0f77866155dd4f2b332a262henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceWarning, 1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRecPayloadType() failed to retrieve RX payload type"); 1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = payloadType; 1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1508d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org "Channel::GetRecPayloadType() => pltype=%d", codec.pltype); 1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15126141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) 1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendCNPayloadType()"); 1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 15196141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int32_t samplingFreqHz(-1); 15204517585db5f2f2a14fdd56a96f4b44f745967c8ctina.legrand@webrtc.org const int kMono = 1; 1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (frequency == kFreq32000Hz) 1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 32000; 1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (frequency == kFreq16000Hz) 1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com samplingFreqHz = 16000; 1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1526eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1) 1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to retrieve default CN codec " 1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "settings"); 1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Modify the payload type (must be set to dynamic range) 1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.pltype = type; 1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1538eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) != 0) 1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to ACM"); 1543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15462853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 15482853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 15492853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 1550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 1553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendCNPayloadType() failed to register CN to RTP/RTCP " 1554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 1555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1561adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.orgint Channel::SetOpusMaxPlaybackRate(int frequency_hz) { 15626aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1563adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org "Channel::SetOpusMaxPlaybackRate()"); 15646aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org 1565adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org if (audio_coding_->SetOpusMaxPlaybackRate(frequency_hz) != 0) { 15666aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org _engineStatisticsPtr->SetLastError( 15676aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 1568adee8f924224e116f041564ddde83c979880e35fminyue@webrtc.org "SetOpusMaxPlaybackRate() failed to set maximum playback rate"); 15696aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org return -1; 15706aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org } 15716aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org return 0; 15726aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org} 15736aac93bd9c3da92e92b016d83c8f84c65aae65b6minyue@webrtc.org 15749b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.orgint Channel::SetOpusDtx(bool enable_dtx) { 15759b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 15769b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org "Channel::SetOpusDtx(%d)", enable_dtx); 15779b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org int ret = enable_dtx ? audio_coding_->EnableOpusDtx(true) 15789b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org : audio_coding_->DisableOpusDtx(); 15799b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org if (ret != 0) { 15809b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org _engineStatisticsPtr->SetLastError( 15819b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, "SetOpusDtx() failed"); 15829b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org return -1; 15839b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org } 15849b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org return 0; 15859b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org} 15869b2e1144df6e3622354caca00baf4a7462a0809cminyue@webrtc.org 15876141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t Channel::RegisterExternalTransport(Transport& transport) 1588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 1590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalTransport()"); 1591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 15929a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_externalTransport) 1595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, 1597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceError, 1598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterExternalTransport() external transport already enabled"); 1599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = true; 1602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = &transport; 1603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16066141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 1607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterExternalTransport() 1608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalTransport()"); 1611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 16129a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 161383661f534e56dfaf3542963b54b1e208f223a377xians@webrtc.org 1614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_transportPtr) 1615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() external transport already " 1619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "disabled"); 1620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _externalTransport = false; 1623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _transportPtr = NULL; 1624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterExternalTransport() all transport is disabled"); 1626684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org return 0; 1627684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 1628684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 16294591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t Channel::ReceivedRTPPacket(const int8_t* data, size_t length, 1630b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org const PacketTime& packet_time) { 16310c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 16320c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTPPacket()"); 1633684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 16340c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTP packet 16351de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(false); 1636684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 16370c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Dump the RTP packet to a file (if RTP dump is enabled). 16386141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org if (_rtpDumpIn.DumpPacket((const uint8_t*)data, 16396141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t)length) == -1) { 16400c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 16410c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VoEId(_instanceId,_channelId), 16420c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::SendPacket() RTP dump to input file failed"); 16430c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 16447bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* received_packet = reinterpret_cast<const uint8_t*>(data); 1645a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org RTPHeader header; 16467bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_header_parser_->Parse(received_packet, length, &header)) { 16477bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 16487bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Incoming packet: invalid RTP header"); 1649a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org return -1; 1650a5cb98cbbd11e93cb6d0a6232387814aac168c7dstefan@webrtc.org } 1651822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org header.payload_type_frequency = 1652822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); 16537bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (header.payload_type_frequency < 0) 1654822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org return -1; 165548df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order = IsPacketInOrder(header); 16567bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->IncomingPacket(header, length, 165748df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org IsPacketRetransmitted(header, in_order)); 16587bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_payload_registry_->SetIncomingPayloadType(header); 1659b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org 1660b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org // Forward any packets to ViE bandwidth estimator, if enabled. 1661b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org { 1662b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 1663b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (vie_network_) { 1664b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org int64_t arrival_time_ms; 1665b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (packet_time.timestamp != -1) { 1666b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org arrival_time_ms = (packet_time.timestamp + 500) / 1000; 1667b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } else { 1668b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org arrival_time_ms = TickTime::MillisecondTimestamp(); 1669b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 16704591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_length = length - header.headerLength; 1671b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_->ReceivedBWEPacket(video_channel_, arrival_time_ms, 1672b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org payload_length, header); 1673b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 1674b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 1675b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org 167648df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1; 16777bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 16787bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 16797bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::ReceivePacket(const uint8_t* packet, 16804591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t packet_length, 16817bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const RTPHeader& header, 16827bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org bool in_order) { 1683456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org if (rtp_payload_registry_->IsRtx(header)) { 1684456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org return HandleRtxPacket(packet, packet_length, header); 1685822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 16867bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org const uint8_t* payload = packet + header.headerLength; 16874591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org assert(packet_length >= header.headerLength); 16884591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t payload_length = packet_length - header.headerLength; 1689822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org PayloadUnion payload_specific; 1690822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, 16917bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org &payload_specific)) { 16927bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 1693822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org } 16947bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, 16957bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org payload_specific, in_order); 16967bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 16977bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 1698456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.orgbool Channel::HandleRtxPacket(const uint8_t* packet, 1699456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org size_t packet_length, 1700456f01441aa4f8c0c8b98aa6d9c2af4a4817e8dbminyue@webrtc.org const RTPHeader& header) { 17017bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_payload_registry_->IsRtx(header)) 17027bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17037bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 17047bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Remove the RTX header and parse the original RTP header. 17057bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (packet_length < header.headerLength) 17067bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17077bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (packet_length > kVoiceEngineMaxIpPacketSizeBytes) 17087bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17097bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (restored_packet_in_use_) { 17107bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 17117bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Multiple RTX headers detected, dropping packet"); 17127bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17130c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 17147bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org uint8_t* restored_packet_ptr = restored_packet_; 17157bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!rtp_payload_registry_->RestoreOriginalPacket( 17167bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(), 17177bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org header)) { 17187bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId, 17197bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org "Incoming RTX packet: invalid RTP header"); 17207bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17217bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org } 17227bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = true; 17237bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length); 17247bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org restored_packet_in_use_ = false; 17257bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return ret; 17267bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org} 17277bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org 17287bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.orgbool Channel::IsPacketInOrder(const RTPHeader& header) const { 17297bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 17307bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 17317bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 17327bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17337bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return statistician->IsPacketInOrder(header.sequenceNumber); 17340c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org} 17350c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 173648df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.orgbool Channel::IsPacketRetransmitted(const RTPHeader& header, 173748df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org bool in_order) const { 17387bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Retransmissions are handled separately if RTX is enabled. 17397bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (rtp_payload_registry_->RtxEnabled()) 17407bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17417bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org StreamStatistician* statistician = 17427bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->GetStatistician(header.ssrc); 17437bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org if (!statistician) 17447bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org return false; 17457bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org // Check if this is a retransmission. 174616825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t min_rtt = 0; 17477bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL); 174848df38114d9502f4b4ad700c011190c608a702d5stefan@webrtc.org return !in_order && 17497bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org statistician->IsRetransmitOfOldPacket(header, min_rtt); 1750822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org} 1751822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 17524591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgint32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) { 17530c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 17540c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::ReceivedRTCPPacket()"); 17550c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Store playout timestamp for the received RTCP packet 17561de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org UpdatePlayoutTimestamp(true); 17570c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org 17580c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Dump the RTCP packet to a file (if RTP dump is enabled). 17594591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org if (_rtpDumpIn.DumpPacket((const uint8_t*)data, length) == -1) { 17600c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 17610c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VoEId(_instanceId,_channelId), 17620c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::SendPacket() RTCP dump to input file failed"); 17630c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 1764684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 17650c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org // Deliver RTCP packet to RTP/RTCP module for parsing 17664591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, length) == -1) { 17670c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 17680c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, 17690c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org "Channel::IncomingRTPPacket() RTCP packet is invalid"); 17700c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org } 177182c4b8531c2c4c2aaf82ff57ee1805037a43ed50wu@webrtc.org 17728e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org { 17738e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 177416825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t rtt = GetRTT(); 17752c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org if (rtt == 0) { 17762c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org // Waiting for valid RTT. 17772c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org return 0; 17782c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org } 17792c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t ntp_secs = 0; 17802c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t ntp_frac = 0; 17812c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org uint32_t rtp_timestamp = 0; 17822c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org if (0 != _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL, 17832c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org &rtp_timestamp)) { 17842c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org // Waiting for RTCP. 17852c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org return 0; 17862c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org } 17872c0cdbce226137a8f755ae0fb51c28a335b2ea5dminyue@webrtc.org ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp); 17888e24d8777849951ed86fb01e0bf556d4eda65161stefan@webrtc.org } 17890c45957e3a6963e1460c0b5b62a6adf43cf44314pwestin@webrtc.org return 0; 1790684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org} 1791684f0577fbe4ea393fef1dddf2ca7d02e3205b49pwestin@webrtc.org 1792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(const char* fileName, 17939213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 17949213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 17959213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 17969213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 17979213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 1798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 1799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d," 1802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " format=%d, volumeScaling=%5.3f, startPosition=%d, " 1803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 1804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 1805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1806944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 1807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 1811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1813470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 18159a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1817b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 1818b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1819b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1820b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1821b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1822b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1824b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 1825b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, (const FileFormats)format); 1826b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1827b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 1828b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1829b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1830b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 183131d30700d638c4cfa47c26cac7cb00c7232874c9henrike@webrtc.org "StartPlayingFileLocally() filePlayer format is not correct"); 1832b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1833b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1834470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 18356141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 1836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1837b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile( 1838b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org fileName, 1839b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org loop, 1840b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org startPosition, 1841b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 1842b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 1843b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, 1844b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const CodecInst*)codecInst) != 0) 1845b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1846b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1847b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_BAD_FILE, kTraceError, 1848b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to start file playout"); 1849b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 1850b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1851b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1852b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1853b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1854b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 1855944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(true); 1856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1857ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1858ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1859066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileLocally(InStream* stream, 18659213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 18669213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 18679213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 18689213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 1869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 1870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileLocally(format=%d," 1873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 1874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 1875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 1877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 1880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() NULL as input stream"); 1881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1885944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().output_file_playing) 1886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceError, 1889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileLocally() is already playing"); 1890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 1891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 18949a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1895b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1896b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Destroy the old instance 1897b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr) 1898b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1899b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1900b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1901b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1902b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1903b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1904b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // Create the instance 1905b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = FilePlayer::CreateFilePlayer( 1906b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerId, 1907b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org (const FileFormats)format); 1908b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1909b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr == NULL) 1910b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1911b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1912b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 1913b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFileLocally() filePlayer format isnot correct"); 1914b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1915b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1916b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 19176141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 1918b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1919b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 1920b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org volumeScaling, 1921b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org notificationTime, 1922b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org stopPosition, codecInst) != 0) 1923b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1924b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 1925b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StartPlayingFile() failed to " 1926b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "start file playout"); 1927b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 1928b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1929b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1930b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1931b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1932b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(this); 1933944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(true); 1934b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1935ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 1936ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (RegisterFilePlayingToMixer() != 0) 1937066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileLocally() 1943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileLocally()"); 1946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1947944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().output_file_playing) 1948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 1949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 1950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 1951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileLocally() isnot playing"); 1952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 19569a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 1957b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org 1958b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org if (_outputFilePlayerPtr->StopPlayingFile() != 0) 1959b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org { 1960b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _engineStatisticsPtr->SetLastError( 1961b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org VE_STOP_RECORDING_FAILED, kTraceError, 1962b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() could not stop playing"); 1963b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org return -1; 1964b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org } 1965b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr->RegisterModuleFileCallback(NULL); 1966b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 1967b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org _outputFilePlayerPtr = NULL; 1968944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 1969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1970b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // _fileCritSect cannot be taken while calling 1971b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // SetAnonymousMixibilityStatus. Refer to comments in 1972b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org // StartPlayingFileLocally(const char* ...) for more details. 1973066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) 1974066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org { 1975066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org _engineStatisticsPtr->SetLastError( 1976066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 1977b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "StopPlayingFile() failed to stop participant from playing as" 1978b37c628ae43a9086da607a638785723306bd9aedhenrike@webrtc.org "file in the mixer"); 1979066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org return -1; 1980066f9e5a2fbb8e83ef88ceca0ab5a4ea057cc619henrike@webrtc.org } 1981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 1983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileLocally() const 1986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 1987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 1988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileLocally()"); 1989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1990944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return channel_state_.Get().output_file_playing; 1991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1993ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.orgint Channel::RegisterFilePlayingToMixer() 1994ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org{ 1995ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // Return success for not registering for file playing to mixer if: 1996ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 1. playing file before playout is started on that channel. 1997ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // 2. starting playout without file playing on that channel. 1998944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().playing || 1999944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org !channel_state_.Get().output_file_playing) 2000ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 2001ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 2002ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 2003ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2004ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // |_fileCritSect| cannot be taken while calling 2005ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // SetAnonymousMixabilityStatus() since as soon as the participant is added 2006ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // frames can be pulled by the mixer. Since the frames are generated from 2007ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org // the file, _fileCritSect will be taken. This would result in a deadlock. 2008ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) 2009ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org { 2010944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetOutputFilePlaying(false); 2011ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2012ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _engineStatisticsPtr->SetLastError( 2013ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError, 2014ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org "StartPlayingFile() failed to add participant as file to mixer"); 2015ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr->StopPlayingFile(); 2016ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr); 2017ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org _outputFilePlayerPtr = NULL; 2018ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return -1; 2019ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org } 2020ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2021ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org return 0; 2022ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org} 2023ab12990b1b8c2410b34c055e73ed04e8a7ee1d85braveyao@webrtc.org 2024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(const char* fileName, 20259213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org bool loop, 20269213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 20279213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 20289213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 20299213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, " 2034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, " 2035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "stopPosition=%d)", fileName, loop, format, volumeScaling, 2036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, stopPosition); 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() filePlayer 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 "StartPlayingFileAsMicrophone() 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( 2071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, 2072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com loop, 2073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com startPosition, 2074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, 2075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime, 2076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, 2077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const CodecInst*)codecInst) != 0) 2078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start file playout"); 2082470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2088944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(true); 2089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartPlayingFileAsMicrophone(InStream* stream, 20949213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org FileFormats format, 20959213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int startPosition, 20969213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org float volumeScaling, 20979213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int stopPosition, 2098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartPlayingFileAsMicrophone(format=%d, " 2102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)", 2103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format, volumeScaling, startPosition, stopPosition); 2104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(stream == NULL) 2106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone NULL as input stream"); 2110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2113944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2114944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 2115944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_file_playing) 2116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_PLAYING, kTraceWarning, 2119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFileAsMicrophone() is playing"); 2120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr) 2125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create the instance 2132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = FilePlayer::CreateFilePlayer( 2133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerId, (const FileFormats)format); 2134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 2136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingInputFile() filePlayer format isnot correct"); 2140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 21436141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); 2144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition, 2146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com volumeScaling, notificationTime, 2147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stopPosition, codecInst) != 0) 2148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartPlayingFile() failed to start " 2151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "file playout"); 2152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->StopPlayingFile(); 2153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2157ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(this); 2159944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(true); 2160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopPlayingFileAsMicrophone() 2165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopPlayingFileAsMicrophone()"); 2168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2169944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2170944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org 2171944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().input_file_playing) 2172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFileAsMicrophone() isnot playing"); 2176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr->StopPlayingFile() != 0) 2180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopPlayingFile() could not stop playing"); 2184470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr->RegisterModuleFileCallback(NULL); 2187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr); 2188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputFilePlayerPtr = NULL; 2189944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputFilePlaying(false); 2190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::IsPlayingFileAsMicrophone() const 2195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::IsPlayingFileAsMicrophone()"); 2198944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org return channel_state_.Get().input_file_playing; 2199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2201813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.orgint Channel::StartRecordingPlayout(const char* fileName, 2202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout(fileName=%s)", fileName); 2206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 22156141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 221840197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org if ((codecInst != NULL) && 221940197d7b3b347f05b299a930641dad131c853e01niklas.enbom@webrtc.org ((codecInst->channels < 1) || (codecInst->channels > 2))) 2220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 22429a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile( 2263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileName, (const CodecInst&)*codecInst, notificationTime) != 0) 2264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 2267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingAudioFile() failed to start file recording"); 2268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StartRecordingPlayout(OutStream* stream, 2280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const CodecInst* codecInst) 2281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRecordingPlayout()"); 2284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecording) 2286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1), 2288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() is already recording"); 2289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileFormats format; 22936141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint32_t notificationTime(0); // Not supported in VoE 2294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst dummyCodec={100,"L16",16000,320,1,320000}; 2295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (codecInst != NULL && codecInst->channels != 1) 2297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_ARGUMENT, kTraceError, 2300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() invalid compression"); 2301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if(codecInst == NULL) 2304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatPcm16kHzFile; 2306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codecInst=&dummyCodec; 2307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) || 2309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) || 2310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (STR_CASE_CMP(codecInst->plname,"PCMA") == 0)) 2311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatWavFile; 2313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 2315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com format = kFileFormatCompressedFile; 2317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23199a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Destroy the old instance 2322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr) 2323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = FileRecorder::CreateFileRecorder( 2330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderId, (const FileFormats)format); 2331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr == NULL) 2332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() fileRecorder format isnot correct"); 2336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst, 2340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com notificationTime) != 0) 2341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError, 2343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRecordingPlayout() failed to " 2344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "start file recording"); 2345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->StopRecording(); 2346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2350ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 2351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(this); 2352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = true; 2353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::StopRecordingPlayout() 2358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1), 2360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRecordingPlayout()"); 2361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputFileRecording) 2363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1), 2365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecordingPlayout() isnot recording"); 2366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 23709a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFileRecorderPtr->StopRecording() != 0) 2373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_STOP_RECORDING_FAILED, kTraceError, 2376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRecording() could not stop recording"); 2377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return(-1); 2378470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr->RegisterModuleFileCallback(NULL); 2380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr); 2381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecorderPtr = NULL; 2382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputFileRecording = false; 2383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 2388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMixWithMicStatus(bool mix) 2389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2390944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 2391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mixFileWithMicrophone=mix; 2392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 23956141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevel(uint32_t& level) const 2396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 23976141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t currentLevel = _outputAudioLevel.Level(); 23986141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 2399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevel() => level=%u", level); 2402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 24066141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgChannel::GetSpeechOutputLevelFullRange(uint32_t& level) const 2407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 24086141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t currentLevel = _outputAudioLevel.LevelFullRange(); 24096141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org level = static_cast<int32_t> (currentLevel); 2410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSpeechOutputLevelFullRange() => level=%u", level); 2413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMute(bool enable) 2418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 241963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMute(enable=%d)", enable); 2422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _mute = enable; 2423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 2427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::Mute() const 2428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 242963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _mute; 2431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetOutputVolumePan(float left, float right) 2435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 243663420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetOutputVolumePan()"); 2439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panLeft = left; 2440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _panRight = right; 2441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetOutputVolumePan(float& left, float& right) const 2446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 244763420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com left = _panLeft; 2449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com right = _panRight; 2450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetOutputVolumePan() => left=%3.2f, right=%3.2f", left, right); 2453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetChannelOutputVolumeScaling(float scaling) 2458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 245963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetChannelOutputVolumeScaling()"); 2462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputGain = scaling; 2463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetChannelOutputVolumeScaling(float& scaling) const 2468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 246963420669746cfca6ed1d902c68c656b79ffa5a1bwu@webrtc.org CriticalSectionScoped cs(&volume_settings_critsect_); 2470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com scaling = _outputGain; 2471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetChannelOutputVolumeScaling() => scaling=%3.2f", scaling); 2474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventOutband(unsigned char eventCode, 2478822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org int lengthMs, int attenuationDb, 2479822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org bool playDtmfEvent) 2480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)", 2483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 2484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playOutbandDtmfEvent = playDtmfEvent; 2486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 24872853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs, 2488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb) != 0) 2489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_DTMF_FAILED, 2492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 2493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendTelephoneEventOutband() failed to send event"); 2494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::SendTelephoneEventInband(unsigned char eventCode, 2500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int lengthMs, 2501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int attenuationDb, 2502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool playDtmfEvent) 2503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)", 2506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com playDtmfEvent); 2507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _playInbandDtmfEvent = playDtmfEvent; 2509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb); 2510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetSendTelephoneEventPayloadType(unsigned char type) 2516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetSendTelephoneEventPayloadType()"); 2519f81f9f8c2a18fb20ee60406ece45ff3210367ff9andrew@webrtc.org if (type > 127) 2520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetSendTelephoneEventPayloadType() invalid type"); 2524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 25265b10d8fb184db0192091bf407c8166b5d03b932epbos@webrtc.org CodecInst codec = {}; 25271da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.plfreq = 8000; 25281da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org codec.pltype = type; 25291da1ce0da5fcc029dbc2a134a9760e1b398b02d7pwestin@webrtc.org memcpy(codec.plname, "telephone-event", 16); 25302853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) 2531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 25324392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _rtpRtcpModule->DeRegisterSendPayload(codec.pltype); 25334392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) { 25344392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org _engineStatisticsPtr->SetLastError( 25354392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 25364392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "SetSendTelephoneEventPayloadType() failed to register send" 25374392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org "payload type"); 25384392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org return -1; 25394392d5f9f859b5d55b8017fafb09a496a110beb3henrika@webrtc.org } 2540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _sendTelephoneEventPayloadType = type; 2542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetSendTelephoneEventPayloadType(unsigned char& type) 2547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetSendTelephoneEventPayloadType()"); 2550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com type = _sendTelephoneEventPayloadType; 2551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetSendTelephoneEventPayloadType() => type=%u", type); 2554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::UpdateRxVadDetection(AudioFrame& audioFrame) 2559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection()"); 2562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com int vadDecision = 1; 2564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 256563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0; 2566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr) 2568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com OnRxVadDetected(vadDecision); 2570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _oldVadDecision = vadDecision; 2571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 2574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::UpdateRxVadDetection() => vadDecision=%d", 2575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com vadDecision); 2576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterRxVadObserver(VoERxVadCallback &observer) 2581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterRxVadObserver()"); 25849a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_rxVadObserverPtr) 2587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 2590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RegisterRxVadObserver() observer already enabled"); 2591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = &observer; 2594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = true; 2595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::DeRegisterRxVadObserver() 2600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterRxVadObserver()"); 26039a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 2604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_rxVadObserverPtr) 2606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 2609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "DeRegisterRxVadObserver() observer already disabled"); 2610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxVadObserverPtr = NULL; 2613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _RxVadDetection = false; 2614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::VoiceActivityIndicator(int &activity) 2619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com activity = _sendFrameType; 2621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 26236c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "Channel::VoiceActivityIndicator(indicator=%d)", activity); 2624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_AGC 2628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 26309213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcStatus(bool enable, AgcModes mode) 2631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcStatus(enable=%d, mode=%d)", 2634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 2635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 26366c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org GainControl::Mode agcMode = kDefaultRxAgcMode; 2637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcDefault: 2640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcUnchanged: 2642f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org agcMode = rx_audioproc_->gain_control()->mode(); 2643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcFixedDigital: 2645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode = GainControl::kFixedDigital; 2646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kAgcAdaptiveDigital: 2648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com agcMode =GainControl::kAdaptiveDigital; 2649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() invalid Agc mode"); 2654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2657f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_mode(agcMode) != 0) 2658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc mode"); 2662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2664f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->Enable(enable) != 0) 2665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcStatus() failed to set Agc state"); 2669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxAgcIsEnabled = enable; 2673944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); 2674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcStatus(bool& enabled, AgcModes& mode) 2680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcStatus(enable=?, mode=?)"); 2683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2684f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org bool enable = rx_audioproc_->gain_control()->is_enabled(); 2685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com GainControl::Mode agcMode = 2686f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->mode(); 2687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 2689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (agcMode) 2691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2692470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kFixedDigital: 2693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcFixedDigital; 2694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case GainControl::kAdaptiveDigital: 2696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kAgcAdaptiveDigital; 2697470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2698470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com default: 2699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxAgcStatus() invalid Agc mode"); 2702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2708470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 27099213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxAgcConfig(AgcConfig config) 2710470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxAgcConfig()"); 2713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2714f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_target_level_dbfs( 2715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv) != 0) 2716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set target peak |level|" 2720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "(or envelope) of the Agc"); 2721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2723f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->set_compression_gain_db( 2724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB) != 0) 2725470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set the range in |gain| the" 2729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " digital compression stage may apply"); 2730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2732f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->gain_control()->enable_limiter( 2733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable) != 0) 2734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 2737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRxAgcConfig() failed to set hard limiter to the signal"); 2738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxAgcConfig(AgcConfig& config) 2746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxAgcConfig(config=%?)"); 2749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv = 2751f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->target_level_dbfs(); 2752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB = 2753f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->compression_gain_db(); 2754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable = 2755f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->gain_control()->is_limiter_enabled(); 2756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), "GetRxAgcConfig() => " 2759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "targetLeveldBOv=%u, digitalCompressionGaindB=%u," 2760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " limiterEnable=%d", 2761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.targetLeveldBOv, 2762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.digitalCompressionGaindB, 2763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com config.limiterEnable); 2764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2765470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2766470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_AGC 2769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WEBRTC_VOICE_ENGINE_NR 2771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 27739213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SetRxNsStatus(bool enable, NsModes mode) 2774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2776470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRxNsStatus(enable=%d, mode=%d)", 2777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (int)enable, (int)mode); 2778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 27796c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org NoiseSuppression::Level nsLevel = kDefaultNsMode; 2780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (mode) 2781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsDefault: 2784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsUnchanged: 2786f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org nsLevel = rx_audioproc_->noise_suppression()->level(); 2787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsConference: 2789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 2790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsLowSuppression: 2792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kLow; 2793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsModerateSuppression: 2795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kModerate; 2796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsHighSuppression: 2798470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kHigh; 2799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2800470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case kNsVeryHighSuppression: 2801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com nsLevel = NoiseSuppression::kVeryHigh; 2802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2805f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->noise_suppression()->set_level(nsLevel) 2806470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com != 0) 2807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 28106c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "SetRxNsStatus() failed to set NS level"); 2811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2813f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org if (rx_audioproc_->noise_suppression()->Enable(enable) != 0) 2814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_APM_ERROR, kTraceError, 28176c264cc92eb554716814db200b84752d4dfb6ba3andrew@webrtc.org "SetRxNsStatus() failed to set NS state"); 2818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _rxNsIsEnabled = enable; 2822944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled); 2823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2826470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2827470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2828470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRxNsStatus(bool& enabled, NsModes& mode) 2829470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2830470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 2831470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRxNsStatus(enable=?, mode=?)"); 2832470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2833470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com bool enable = 2834f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->noise_suppression()->is_enabled(); 2835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NoiseSuppression::Level ncLevel = 2836f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org rx_audioproc_->noise_suppression()->level(); 2837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2838470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = enable; 2839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com switch (ncLevel) 2841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2842470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kLow: 2843470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsLowSuppression; 2844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kModerate: 2846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsModerateSuppression; 2847470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2848470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kHigh: 2849470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsHighSuppression; 2850470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com case NoiseSuppression::kVeryHigh: 2852470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mode = kNsVeryHighSuppression; 2853470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com break; 2854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2856470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRxNsStatus() => enabled=%d, mode=%d", enabled, mode); 2859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif // #ifdef WEBRTC_VOICE_ENGINE_NR 2863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetLocalSSRC(unsigned int ssrc) 2866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2867470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetLocalSSRC()"); 2869944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().sending) 2870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_ALREADY_SENDING, kTraceError, 2873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetLocalSSRC() already sending"); 2874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2876ef92755780253c6a7940c89598a206e58e05b810stefan@webrtc.org _rtpRtcpModule->SetSSRC(ssrc); 2877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetLocalSSRC(unsigned int& ssrc) 2882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 28832853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org ssrc = _rtpRtcpModule->SSRC(); 2884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetLocalSSRC() => ssrc=%lu", ssrc); 2887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteSSRC(unsigned int& ssrc) 2892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2893822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org ssrc = rtp_receiver_->SSRC(); 2894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteSSRC() => ssrc=%lu", ssrc); 2897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2900ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) { 2901f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org _includeAudioLevelIndication = enable; 2902ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id); 2903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2904f3930e941c15da48c037c62cdb1eebbcbf89c9c7andrew@webrtc.org 290593fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.orgint Channel::SetReceiveAudioLevelIndicationStatus(bool enable, 290693fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org unsigned char id) { 290793fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org rtp_header_parser_->DeregisterRtpHeaderExtension( 290893fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org kRtpExtensionAudioLevel); 290993fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( 291093fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org kRtpExtensionAudioLevel, id)) { 291193fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org return -1; 291293fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org } 291393fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org return 0; 291493fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org} 291593fd25c20c688961569d3631b875c8ee0dfc2a80wu@webrtc.org 2916ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) { 2917ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return SetSendRtpHeaderExtension(enable, kRtpExtensionAbsoluteSendTime, id); 2918ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org} 2919ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org 2920ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id) { 2921ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org rtp_header_parser_->DeregisterRtpHeaderExtension( 2922ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org kRtpExtensionAbsoluteSendTime); 2923b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension( 2924b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org kRtpExtensionAbsoluteSendTime, id)) { 2925b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org return -1; 2926ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org } 2927ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return 0; 2928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2930d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgvoid Channel::SetRTCPStatus(bool enable) { 2931d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2932d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "Channel::SetRTCPStatus()"); 2933d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetRTCPStatus(enable ? kRtcpCompound : kRtcpOff); 2934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTCPStatus(bool& enabled) 2938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 29392853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 2940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled = (method != kRtcpOff); 2941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId,_channelId), 2943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTCPStatus() => enabled=%d", enabled); 2944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetRTCP_CNAME(const char cName[256]) 2949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 2951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetRTCP_CNAME()"); 29522853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetCNAME(cName) != 0) 2953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2954470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2955470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 2956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetRTCP_CNAME() failed to set RTCP CNAME"); 2957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2963470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCP_CNAME(char cName[256]) 2964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (cName == NULL) 2966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 2969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() invalid CNAME input buffer"); 2970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2972813e4b0af06272dada388c2d8383b2e36a1da6a6leozwang@webrtc.org char cname[RTCP_CNAME_SIZE]; 2973822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org const uint32_t remoteSSRC = rtp_receiver_->SSRC(); 29742853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) 2975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 2976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 2977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_CANNOT_RETRIEVE_CNAME, kTraceError, 2978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME"); 2979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 2980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 2981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com strcpy(cName, cname); 2982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 2983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 2984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCP_CNAME() => cName=%s", cName); 2985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 2986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 2987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 2989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRemoteRTCPData( 2990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPHigh, 2991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& NTPLow, 2992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& timestamp, 2993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& playoutTimestamp, 2994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int* jitter, 2995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short* fractionLost) 2996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 2997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Information from sender info in received Sender Reports 2998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTCPSenderInfo senderInfo; 30002853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) 3001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3004fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "GetRemoteRTCPData() failed to retrieve sender info for remote " 3005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "side"); 3006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We only utilize 12 out of 20 bytes in the sender info (ignores packet 3010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // and octet count) 3011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh = senderInfo.NTPseconds; 3012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPLow = senderInfo.NTPfraction; 3013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com timestamp = senderInfo.RTPtimeStamp; 3014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => NTPHigh=%lu, NTPLow=%lu, " 3018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "timestamp=%lu", 3019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com NTPHigh, NTPLow, timestamp); 3020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Locally derived information 3022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // This value is updated on each incoming RTCP packet (0 when no packet 3024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has been received) 30251de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playoutTimestamp = playout_timestamp_rtcp_; 3026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3028470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRemoteRTCPData() => playoutTimestamp=%lu", 30301de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_); 3031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3032470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL != jitter || NULL != fractionLost) 3033470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3034ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Get all RTCP receiver report blocks that have been received on this 3035ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // channel. If we receive RTP packets from a remote source we know the 3036ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // remote SSRC and use the report block from him. 3037ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Otherwise use the first report block. 3038ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock> remote_stats; 30392853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 || 3040ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remote_stats.empty()) { 3041ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3042ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org VoEId(_instanceId, _channelId), 3043ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org "GetRemoteRTCPData() failed to measure statistics due" 3044ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org " to lack of received RTP and/or RTCP packets"); 3045ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org return -1; 3046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3047ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 3048822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org uint32_t remoteSSRC = rtp_receiver_->SSRC(); 3049ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin(); 3050ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org for (; it != remote_stats.end(); ++it) { 3051ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it->remoteSSRC == remoteSSRC) 3052ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org break; 3053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3054ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 3055ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org if (it == remote_stats.end()) { 3056ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // If we have not received any RTCP packets from this SSRC it probably 3057ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // means that we have not received any RTP packets. 3058ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org // Use the first received report block instead. 3059ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org it = remote_stats.begin(); 3060ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org remoteSSRC = it->remoteSSRC; 3061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3062ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 306379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (jitter) { 306479af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *jitter = it->jitter; 306579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 306679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 306779af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => jitter = %lu", *jitter); 306879af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 3069ce5990cb0bbfbf5ee5306cf990e975a2faa090b7perkj@webrtc.org 307079af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org if (fractionLost) { 307179af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost = it->fractionLost; 307279af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 307379af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org VoEId(_instanceId, _channelId), 307479af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org "GetRemoteRTCPData() => fractionLost = %lu", 307579af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org *fractionLost); 307679af734807109d119573ce23daa1a2bff0f0eecaxians@webrtc.org } 3077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 30829213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::SendApplicationDefinedRTCPPacket(unsigned char subType, 3083470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int name, 3084470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com const char* data, 3085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned short dataLengthInBytes) 3086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SendApplicationDefinedRTCPPacket()"); 3089944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (!channel_state_.Get().sending) 3090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_NOT_SENDING, kTraceError, 3093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() not sending"); 3094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (NULL == data) 3097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid data value"); 3101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (dataLengthInBytes % 4 != 0) 3104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() invalid length value"); 3108470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 31102853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org RTCPMethod status = _rtpRtcpModule->RTCP(); 3111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (status == kRtcpOff) 3112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTCP_ERROR, kTraceError, 3115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() RTCP is disabled"); 3116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Create and schedule the RTCP APP packet for transmission 31202853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SetRTCPApplicationSpecificData( 3121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com subType, 3122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com name, 3123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (const unsigned char*) data, 3124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com dataLengthInBytes) != 0) 3125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_SEND_ERROR, kTraceError, 3128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SendApplicationDefinedRTCPPacket() failed to send RTCP packet"); 3129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics( 3136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& averageJitterMs, 3137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& maxJitterMs, 3138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com unsigned int& discardedPackets) 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 if (_rtpRtcpModule->RTCP() == kRtcpOff) { 314354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // If RTCP is off, there is no timed thread in the RTCP module regularly 314454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // generating new stats, trigger the update manually here instead. 314554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org StreamStatistician* statistician = 314654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); 314754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (statistician) { 314854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Don't use returned statistics, use data from proxy instead so that 314954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // max jitter can be fetched atomically. 315054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics s; 315154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org statistician->GetStatistics(&s, true); 315254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 3153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 315554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ChannelStatistics stats = statistics_proxy_->GetStats(); 3156eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org const int32_t playoutFrequency = audio_coding_->PlayoutFrequency(); 315754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org if (playoutFrequency > 0) { 315854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Scale RTP statistics given the current playout frequency 315954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org maxJitterMs = stats.max_jitter / (playoutFrequency / 1000); 316054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000); 3161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com discardedPackets = _numberOfDiscardedPackets; 3164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => averageJitterMs = %lu, maxJitterMs = %lu," 3168fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " discardedPackets = %lu)", 3169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com averageJitterMs, maxJitterMs, discardedPackets); 3170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 31738a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.orgint Channel::GetRemoteRTCPReportBlocks( 31748a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<ReportBlock>* report_blocks) { 31758a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (report_blocks == NULL) { 31768a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError, 31778a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlock()s invalid report_blocks."); 31788a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 31798a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 31808a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31818a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Get the report blocks from the latest received RTCP Sender or Receiver 31828a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // Report. Each element in the vector contains the sender's SSRC and a 31838a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org // report block according to RFC 3550. 31848a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock> rtcp_report_blocks; 31858a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) { 31868a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org _engineStatisticsPtr->SetLastError(VE_RTP_RTCP_MODULE_ERROR, kTraceError, 31878a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org "GetRemoteRTCPReportBlocks() failed to read RTCP SR/RR report block."); 31888a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return -1; 31898a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 31908a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31918a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org if (rtcp_report_blocks.empty()) 31928a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 31938a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 31948a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin(); 31958a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org for (; it != rtcp_report_blocks.end(); ++it) { 31968a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org ReportBlock report_block; 31978a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.sender_SSRC = it->remoteSSRC; 31988a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.source_SSRC = it->sourceSSRC; 31998a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.fraction_lost = it->fractionLost; 32008a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.cumulative_num_packets_lost = it->cumulativeLost; 32018a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.extended_highest_sequence_number = it->extendedHighSeqNum; 32028a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.interarrival_jitter = it->jitter; 32038a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.last_SR_timestamp = it->lastSR; 32048a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_block.delay_since_last_SR = it->delaySinceLastSR; 32058a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org report_blocks->push_back(report_block); 32068a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org } 32078a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org return 0; 32088a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org} 32098a2fc88459dc507a67594e3127143e16af612fc9henrika@webrtc.org 3210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetRTPStatistics(CallStatistics& stats) 3212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3213cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- RtcpStatistics 3214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The jitter statistics is updated for each received RTP packet and is 3216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // based on received packets. 321754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics statistics; 3218286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician* statistician = 3219286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC()); 3220286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (!statistician || !statistician->GetStatistics( 3221822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) { 3222822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org _engineStatisticsPtr->SetLastError( 3223822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning, 3224822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org "GetRTPStatistics() failed to read RTP statistics from the " 3225822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org "RTP/RTCP module"); 3226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3228822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.fractionLost = statistics.fraction_lost; 3229822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.cumulativeLost = statistics.cumulative_lost; 3230822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.extendedMax = statistics.extended_max_sequence_number; 3231822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org stats.jitterSamples = statistics.jitter; 3232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() => fractionLost=%lu, cumulativeLost=%lu," 3236fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " extendedMax=%lu, jitterSamples=%li)", 3237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.fractionLost, stats.cumulativeLost, stats.extendedMax, 3238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.jitterSamples); 3239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3240cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- RTT 32412b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org stats.rttMs = GetRTT(); 32426fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org if (stats.rttMs == 0) { 32436fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId), 32446fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org "GetRTPStatistics() failed to get RTT"); 32456fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org } else { 32466fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId), 324716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org "GetRTPStatistics() => rttMs=%" PRId64, stats.rttMs); 32486fd930842055525b5c7cff412735515dd463571aminyue@webrtc.org } 3249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3250cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- Data counters 3251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 32524591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytesSent(0); 32536141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsSent(0); 32544591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytesReceived(0); 32556141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint32_t packetsReceived(0); 3256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3257286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org if (statistician) { 3258286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->GetDataCounters(&bytesReceived, &packetsReceived); 3259286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 3260822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org 32612853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->DataCountersRTP(&bytesSent, 3262822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org &packetsSent) != 0) 3263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "GetRTPStatistics() failed to retrieve RTP datacounters =>" 3267fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org " output will not be complete"); 3268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent = bytesSent; 3271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsSent = packetsSent; 3272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesReceived = bytesReceived; 3273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived = packetsReceived; 3274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 32774591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org "GetRTPStatistics() => bytesSent=%" PRIuS ", packetsSent=%d," 32784591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org " bytesReceived=%" PRIuS ", packetsReceived=%d)", 3279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.bytesSent, stats.packetsSent, stats.bytesReceived, 3280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com stats.packetsReceived); 3281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3282cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org // --- Timestamps 3283cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org { 3284cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org CriticalSectionScoped lock(ts_stats_lock_.get()); 3285cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_; 3286cb711f77d2ff9ebd42678869a73353809b3af66ewu@webrtc.org } 3287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3290c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgint Channel::SetREDStatus(bool enable, int redPayloadtype) { 329142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3292c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "Channel::SetREDStatus()"); 329342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 32948c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (enable) { 32958c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (redPayloadtype < 0 || redPayloadtype > 127) { 32968c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 32978c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_PLTYPE_ERROR, kTraceError, 3298c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "SetREDStatus() invalid RED payload type"); 32998c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 33008c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 33018c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org 33028c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org if (SetRedPayloadType(redPayloadtype) < 0) { 33038c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org _engineStatisticsPtr->SetLastError( 33048c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 33058c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org "SetSecondarySendCodec() Failed to register RED ACM"); 33068c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org return -1; 33078c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org } 330842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 33092cf22a6abce2d38e673505a4cfd5624a3710b5cdperkj@webrtc.org 3310aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org if (audio_coding_->SetREDStatus(enable) != 0) { 331142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 331242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3313aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org "SetREDStatus() failed to set RED state in the ACM"); 331442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 331542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 331642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 3317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3320c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgChannel::GetREDStatus(bool& enabled, int& redPayloadtype) 3321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3322aa5ea1c0f9d0df583ae0f791f6715a0764aff3cfminyue@webrtc.org enabled = audio_coding_->REDStatus(); 3323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (enabled) 3324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 33256141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t payloadType(0); 33262853dde5201d9ddc284ce5efb9688f6340487acepwestin@webrtc.org if (_rtpRtcpModule->SendREDPayloadType(payloadType) != 0) 3327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_RTP_RTCP_MODULE_ERROR, kTraceError, 3330c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() failed to retrieve RED PT from RTP/RTCP " 3331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "module"); 3332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3334df9a41d2701d321dbc987201ec7cffe2a16bd2c4pkasting@chromium.org redPayloadtype = payloadType; 3335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3337c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() => enabled=%d, redPayloadtype=%d", 3338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com enabled, redPayloadtype); 3339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3343c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetREDStatus() => enabled=%d", enabled); 3344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3347c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgint Channel::SetCodecFECStatus(bool enable) { 3348c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3349c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "Channel::SetCodecFECStatus()"); 3350c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3351c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org if (audio_coding_->SetCodecFEC(enable) != 0) { 3352c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org _engineStatisticsPtr->SetLastError( 3353c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3354c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "SetCodecFECStatus() failed to set FEC state"); 3355c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return -1; 3356c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org } 3357c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return 0; 3358c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 3359c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3360c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.orgbool Channel::GetCodecFECStatus() { 3361c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org bool enabled = audio_coding_->CodecFEC(); 3362c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 3363c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org VoEId(_instanceId, _channelId), 3364c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org "GetCodecFECStatus() => enabled=%d", enabled); 3365c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org return enabled; 3366c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org} 3367c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 3368db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.orgvoid Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) { 3369db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org // None of these functions can fail. 3370db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets); 33717bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receive_statistics_->SetMaxReorderingThreshold(maxNumberOfPackets); 33727bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff); 3373d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org if (enable) 3374eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->EnableNack(maxNumberOfPackets); 3375d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org else 3376eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->DisableNack(); 3377db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org} 3378db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org 3379d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.org// Called when we are missing one or more packets. 3380d30859e58e2c0b0676ab2b52b8a2723e10d49e28pwestin@webrtc.orgint Channel::ResendPackets(const uint16_t* sequence_numbers, int length) { 3381db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org return _rtpRtcpModule->SendNACK(sequence_numbers, length); 3382db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org} 3383db249956807d916729aacfaf3382923e8239d533pwestin@webrtc.org 3384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StartRTPDump(const char fileNameUTF8[1024], 3386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RTPDirections direction) 3387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StartRTPDump()"); 3390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 3391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() invalid RTP direction"); 3395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 3398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 3399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 3400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 3402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->IsActive()) 3405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com rtpDumpPtr->Stop(); 3407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr->Start(fileNameUTF8) != 0) 3409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_BAD_FILE, kTraceError, 3412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StartRTPDump() failed to create file"); 3413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::StopRTPDump(RTPDirections direction) 3420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::StopRTPDump()"); 3423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && (direction != kRtpOutgoing)) 3424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "StopRTPDump() invalid RTP direction"); 3428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 3431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 3432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (rtpDumpPtr == NULL) 3433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com assert(false); 3435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!rtpDumpPtr->IsActive()) 3438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->Stop(); 3442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool 3445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RTPDumpIsActive(RTPDirections direction) 3446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((direction != kRtpIncoming) && 3448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (direction != kRtpOutgoing)) 3449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "RTPDumpIsActive() invalid RTP direction"); 3453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return false; 3454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com RtpDump* rtpDumpPtr = (direction == kRtpIncoming) ? 3456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com &_rtpDumpIn : &_rtpDumpOut; 3457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return rtpDumpPtr->IsActive(); 3458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3460b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.orgvoid Channel::SetVideoEngineBWETarget(ViENetwork* vie_network, 3461b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org int video_channel) { 3462b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3463b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (vie_network_) { 3464b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_->Release(); 3465b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_ = NULL; 3466b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 3467b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org video_channel_ = -1; 3468b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org 3469b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org if (vie_network != NULL && video_channel != -1) { 3470b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org vie_network_ = vie_network; 3471b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org video_channel_ = video_channel; 3472b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org } 3473b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org} 3474b1f50100757036cf475072c26f5f374eee9588casolenberg@webrtc.org 34756141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 3476755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.orgChannel::Demultiplex(const AudioFrame& audioFrame) 3477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3479755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org "Channel::Demultiplex()"); 3480ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.CopyFrom(audioFrame); 348163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 3482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 34852f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.orgvoid Channel::Demultiplex(const int16_t* audio_data, 34868fff1f065ea9d25970c3839294acdd606a5ddf22xians@webrtc.org int sample_rate, 34872f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org int number_of_frames, 34888fff1f065ea9d25970c3839294acdd606a5ddf22xians@webrtc.org int number_of_channels) { 34892f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org CodecInst codec; 34902f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org GetSendCodec(codec); 34912f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org 349240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org if (!mono_recording_audio_.get()) { 349340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org // Temporary space for DownConvertToCodecFormat. 349440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mono_recording_audio_.reset(new int16_t[kMaxMonoDataSizeSamples]); 34952f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org } 349640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org DownConvertToCodecFormat(audio_data, 349740ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org number_of_frames, 349840ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org number_of_channels, 349940ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org sample_rate, 350040ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codec.channels, 350140ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org codec.plfreq, 350240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org mono_recording_audio_.get(), 350340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org &input_resampler_, 350440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org &_audioFrame); 35052f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org} 35062f84afad30b088ddebb4063bc47ac9a79d735a2bxians@webrtc.org 35076141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 35080b0665acc1464d68e878f203bbc8772a0e32402dxians@google.comChannel::PrepareEncodeAndSend(int mixingFrequency) 3509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend()"); 3512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 351363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 3514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::PrepareEncodeAndSend() invalid audio frame"); 3517eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3520944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_file_playing) 3521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com MixOrReplaceAudioWithFile(mixingFrequency); 3523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 352521299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org bool is_muted = Mute(); // Cache locally as Mute() takes a lock. 352621299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org if (is_muted) { 352721299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org AudioFrameOperations::Mute(_audioFrame); 3528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3530944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().input_external_media) 3531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 35329a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 353363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org const bool isStereo = (_audioFrame.num_channels_ == 2); 3534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 3535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr->Process( 3537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _channelId, 3538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kRecordingPerChannel, 35396141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (int16_t*)_audioFrame.data_, 354063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.samples_per_channel_, 354163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.sample_rate_hz_, 3542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com isStereo); 3543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com InsertInbandDtmfTone(); 3547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 354860730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org if (_includeAudioLevelIndication) { 3549382c0c209d323c1e6972d988a7b26f08fc2e8a6bandrew@webrtc.org int length = _audioFrame.samples_per_channel_ * _audioFrame.num_channels_; 355021299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org if (is_muted) { 355121299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org rms_level_.ProcessMuted(length); 355221299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org } else { 355321299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org rms_level_.Process(_audioFrame.data_, length); 355421299d4e00781e199a53ba33ec192cdce920acecandrew@webrtc.org } 3555755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org } 3556755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 3557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 35606141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orguint32_t 3561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::EncodeAndSend() 3562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 3564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend()"); 3565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 356663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.num_channels_ <= 2); 356763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (_audioFrame.samples_per_channel_ == 0) 3568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 3570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() invalid audio frame"); 3571eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 357463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.id_ = _channelId; 3575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz. 3577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // The ACM resamples internally. 357963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _audioFrame.timestamp_ = _timeStamp; 3580f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // This call will trigger AudioPacketizationCallback::SendData if encoding 3581f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // is done and payload is ready for packetization and transmission. 3582f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org // Otherwise, it will return without invoking the callback. 3583f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0) 3584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId), 3586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() ACM encoding failed"); 3587eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org return 0xFFFFFFFF; 3588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 359063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org _timeStamp += _audioFrame.samples_per_channel_; 3591f56c1623103e3f72198d6b0f50de9f0585b6f52fhenrik.lundin@webrtc.org return 0; 3592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::RegisterExternalMediaProcessing( 3595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com ProcessingTypes type, 3596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEMediaProcess& processObject) 3597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing()"); 3600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36019a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 3604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputExternalMediaCallbackPtr) 3606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 3610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 3611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = &processObject; 3614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = true; 3615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3616470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 3617470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3618470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputExternalMediaCallbackPtr) 3619470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3620470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceError, 3622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterExternalMediaProcessing() " 3623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already enabled"); 3624470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = &processObject; 3627944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputExternalMedia(true); 3628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3631470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) 3633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing()"); 3636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36379a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 3638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (kPlaybackPerChannel == type) 3640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_outputExternalMediaCallbackPtr) 3642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 3646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "output external media already disabled"); 3647470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3649470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMedia = false; 3650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputExternalMediaCallbackPtr = NULL; 3651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else if (kRecordingPerChannel == type) 3653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!_inputExternalMediaCallbackPtr) 3655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_OPERATION, kTraceWarning, 3658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::DeRegisterExternalMediaProcessing() " 3659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "input external media already disabled"); 3660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3662944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org channel_state_.SetInputExternalMedia(false); 3663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inputExternalMediaCallbackPtr = NULL; 3664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 36691b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.comint Channel::SetExternalMixing(bool enabled) { 36701b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 36711b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing(enabled=%d)", enabled); 36721b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 3673944cbeb2926feb86a687e5fda9e2ac88ea8e3001henrika@webrtc.org if (channel_state_.Get().playing) 36741b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com { 36751b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _engineStatisticsPtr->SetLastError( 36761b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com VE_INVALID_OPERATION, kTraceError, 36771b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "Channel::SetExternalMixing() " 36781b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com "external mixing cannot be changed while playing."); 36791b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return -1; 36801b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com } 36811b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 36821b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com _externalMixing = enabled; 36831b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 36841b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com return 0; 36851b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com} 36861b60ceb499ee35460886f2bfaecee1f47319f925roosa@google.com 3687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3688470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::GetNetworkStatistics(NetworkStatistics& stats) 3689470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3690470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3691470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetNetworkStatistics()"); 3692c0bd7be0df67735d63f5cdd302a3b85f88239874minyue@webrtc.org return audio_coding_->GetNetworkStatistics(&stats); 3693470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 369524301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.orgvoid Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const { 369624301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org audio_coding_->GetDecodingCallStatistics(stats); 369724301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org} 369824301a67c66e6091418e83da49cfb367ef2c6645wu@webrtc.org 36991de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgbool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms, 37001de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org int* playout_buffer_delay_ms) const { 37011de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_average_jitter_buffer_delay_us == 0) { 3702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 37031de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate() no valid estimate."); 37041de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return false; 37051de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 37061de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 + 37071de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _recPacketDelayMs; 37081de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org *playout_buffer_delay_ms = playout_delay_ms_; 37091de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 37101de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetDelayEstimate()"); 37111de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return true; 3712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 37146388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.orgint Channel::SetInitialPlayoutDelay(int delay_ms) 37156388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org{ 37166388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 37176388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "Channel::SetInitialPlayoutDelay()"); 37186388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org if ((delay_ms < kVoiceEngineMinMinPlayoutDelayMs) || 37196388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org (delay_ms > kVoiceEngineMaxMinPlayoutDelayMs)) 37206388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 37216388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 37226388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_INVALID_ARGUMENT, kTraceError, 37236388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() invalid min delay"); 37246388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 37256388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 3726eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetInitialPlayoutDelay(delay_ms) != 0) 37276388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org { 37286388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org _engineStatisticsPtr->SetLastError( 37296388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 37306388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org "SetInitialPlayoutDelay() failed to set min playout delay"); 37316388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return -1; 37326388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org } 37336388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org return 0; 37346388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org} 37356388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 37366388c3e2fdfc91b3648fb7d408a14ddb25e41cd1turaj@webrtc.org 3737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::SetMinimumPlayoutDelay(int delayMs) 3739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetMinimumPlayoutDelay()"); 3742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) || 3743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) 3744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_INVALID_ARGUMENT, kTraceError, 3747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() invalid min delay"); 3748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3750eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) 3751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _engineStatisticsPtr->SetLastError( 3753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 3754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "SetMinimumPlayoutDelay() failed to set min playout delay"); 3755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 37601de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgvoid Channel::UpdatePlayoutTimestamp(bool rtcp) { 37611de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint32_t playout_timestamp = 0; 37621de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 3763eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1) { 37641ebd2e96df5b6d1c30d18b3ce8b928f99666c53fturaj@webrtc.org // This can happen if this channel has not been received any RTP packet. In 37651ebd2e96df5b6d1c30d18b3ce8b928f99666c53fturaj@webrtc.org // this case, NetEq is not capable of computing playout timestamp. 37661de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 37671de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 37681de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 37691de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t delay_ms = 0; 37701de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) { 37711de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 37721de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePlayoutTimestamp() failed to read playout" 37731de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org " delay from the ADM"); 37741de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 37751de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 37761de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "UpdatePlayoutTimestamp() failed to retrieve playout delay"); 37771de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 37781de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 37791de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 3780167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org jitter_buffer_playout_timestamp_ = playout_timestamp; 3781167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org 37821de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Remove the playout delay. 378394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000)); 37841de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 37851de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 37861de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu", 37871de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp); 37881de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 37891de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (rtcp) { 37901de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtcp_ = playout_timestamp; 37911de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } else { 37921de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_timestamp_rtp_ = playout_timestamp; 37931de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 37941de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org playout_delay_ms_ = delay_ms; 37951de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org} 37961de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 37971de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgint Channel::GetPlayoutTimestamp(unsigned int& timestamp) { 37981de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 37991de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::GetPlayoutTimestamp()"); 38001de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (playout_timestamp_rtp_ == 0) { 38011de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _engineStatisticsPtr->SetLastError( 38021de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VE_CANNOT_RETRIEVE_VALUE, kTraceError, 38031de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() failed to retrieve timestamp"); 38041de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return -1; 38051de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 38061de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org timestamp = playout_timestamp_rtp_; 38071de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, 38081de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org VoEId(_instanceId,_channelId), 38091de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "GetPlayoutTimestamp() => timestamp=%u", timestamp); 38101de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return 0; 3811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3813d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint Channel::SetInitTimestamp(unsigned int timestamp) { 3814d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::SetInitTimestamp()"); 3816d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org if (channel_state_.Get().sending) { 3817d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _engineStatisticsPtr->SetLastError(VE_SENDING, kTraceError, 3818d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "SetInitTimestamp() already sending"); 3819d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return -1; 3820d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org } 3821d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetStartTimestamp(timestamp); 3822d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return 0; 3823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3825d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.orgint Channel::SetInitSequenceNumber(short sequenceNumber) { 3826d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId), 3827d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org "Channel::SetInitSequenceNumber()"); 3828d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org if (channel_state_.Get().sending) { 3829d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _engineStatisticsPtr->SetLastError( 3830d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org VE_SENDING, kTraceError, "SetInitSequenceNumber() already sending"); 3831d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return -1; 3832d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org } 3833d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org _rtpRtcpModule->SetSequenceNumber(sequenceNumber); 3834d16e839c6d29831e79312180085b6a19149df43fpbos@webrtc.org return 0; 3835470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3836470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3837470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3838822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.orgChannel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const 3839470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3840470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 3841470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::GetRtpRtcp()"); 3842822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org *rtpRtcpModule = _rtpRtcpModule.get(); 3843822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org *rtp_receiver = rtp_receiver_.get(); 3844470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3845470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3846470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3847e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use 3848e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org// a shared helper. 38496141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 38509213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.orgChannel::MixOrReplaceAudioWithFile(int mixingFrequency) 3851470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 385200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[640]); 3853e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 3854470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3855470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 38569a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3857470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inputFilePlayerPtr == NULL) 3859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3860470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3861470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3862470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() fileplayer" 3863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " doesnt exist"); 3864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3865470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3866470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3867d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 3868470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 3869470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 3870470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3872470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3873470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file mixing " 3874470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "failed"); 3875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (fileSamples == 0) 3878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixOrReplaceAudioWithFile() file is ended"); 3882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 388663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == fileSamples); 3887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_mixFileWithMicrophone) 3889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3890d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3891d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 389240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixWithSat(_audioFrame.data_, 389340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org _audioFrame.num_channels_, 389440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 389540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1, 389640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples); 3897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3898470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3900d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Replace ACM audio with file. 3901d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3902d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 3903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _audioFrame.UpdateFrame(_channelId, 3904eec6ecdb1e249871dd25d04b62fc9ddc03dc8a34tommi@webrtc.org 0xFFFFFFFF, 3905d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org fileBuffer.get(), 3906e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org fileSamples, 3907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency, 3908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kNormalSpeech, 3909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com AudioFrame::kVadUnknown, 3910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1); 3911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 39166141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 3917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::MixAudioWithFile(AudioFrame& audioFrame, 39189213521ea98b0977c7cdabd2853060835af226f3pbos@webrtc.org int mixingFrequency) 3919470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 39202a8df7c375c73a3f477ee5cd9d85336a98f57ee2minyue@webrtc.org assert(mixingFrequency <= 48000); 3921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 392200b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[960]); 3923e59a0aca6a0762592644ebc0282dbe244162eb8dandrew@webrtc.org int fileSamples(0); 3924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 39269a065d1eae9ed296e1e2eaaad73d7ca1223bfe79mflodman@webrtc.org CriticalSectionScoped cs(&_fileCritSect); 3927470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_outputFilePlayerPtr == NULL) 3929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3930470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 3933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We should get the frequency we ask for. 3937d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(), 3938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com fileSamples, 3939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com mixingFrequency) == -1) 3940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 3942470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 3943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::MixAudioWithFile() file mixing failed"); 3944470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 394863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (audioFrame.samples_per_channel_ == fileSamples) 3949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3950d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // Currently file stream is always mono. 3951d713143d99b205aaaa589b96443d82b36c3843e4braveyao@webrtc.org // TODO(xians): Change the code when FilePlayer supports real stereo. 395240ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org MixWithSat(audioFrame.data_, 395340ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org audioFrame.num_channels_, 395440ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileBuffer.get(), 395540ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org 1, 395640ee3d07eda24b8e8214429d9885d9ad9a2c04f7andrew@webrtc.org fileSamples); 3957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 3959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId), 396163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org "Channel::MixAudioWithFile() samples_per_channel_(%d) != " 3962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "fileSamples(%d)", 396363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org audioFrame.samples_per_channel_, fileSamples); 3964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 3965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3966470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3967470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 3968470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 3969470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint 3971470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::InsertInbandDtmfTone() 3972470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 3973af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Check if we should start a new tone. 3974470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfQueue.PendingDtmf() && 3975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com !_inbandDtmfGenerator.IsAddingTone() && 3976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.DelaySinceLastTone() > 3977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kMinTelephoneEventSeparationMs) 3978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 39796141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int8_t eventCode(0); 39806141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t lengthMs(0); 39816141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint8_t attenuationDb(0); 3982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb); 3984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb); 3985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_playInbandDtmfEvent) 3986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 3987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add tone to output mixer using a reduced length to minimize 3988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // risk of echo. 3989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80, 3990470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com attenuationDb); 3991470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 3993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 3994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.IsAddingTone()) 3995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 39966141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t frequency(0); 3997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.GetSampleRate(frequency); 3998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 399963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org if (frequency != _audioFrame.sample_rate_hz_) 4000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Update sample rate of Dtmf tone since the mixing frequency 4002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // has changed. 4003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.SetSampleRate( 40046141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org (uint16_t) (_audioFrame.sample_rate_hz_)); 4005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Reset the tone to be added taking the new sample rate into 4006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // account. 4007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.ResetTone(); 4008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4009ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 40106141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org int16_t toneBuffer[320]; 40116141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org uint16_t toneSamples(0); 4012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Get 10ms tone segment and set time since last tone to zero 4013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1) 4014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceWarning, kTraceVoice, 4016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::EncodeAndSend() inserting Dtmf failed"); 4018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4021af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org // Replace mixed audio with DTMF tone. 4022ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org for (int sample = 0; 402363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org sample < _audioFrame.samples_per_channel_; 4024af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org sample++) 4025af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 4026ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org for (int channel = 0; 4027ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org channel < _audioFrame.num_channels_; 4028af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org channel++) 4029af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org { 4030ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org const int index = sample * _audioFrame.num_channels_ + channel; 4031ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org _audioFrame.data_[index] = toneBuffer[sample]; 4032af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 4033af26f646165e7e2a8747fd54e92e73f48118a807niklas.enbom@webrtc.org } 4034ae1a58bba4f926d149a5f39243269c3f6625f494andrew@webrtc.org 403563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org assert(_audioFrame.samples_per_channel_ == toneSamples); 4036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } else 4037470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Add 10ms to "delay-since-last-tone" counter 4039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com _inbandDtmfGenerator.UpdateDelaySinceLastTone(); 4040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return 0; 4042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40446141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.orgint32_t 40454591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgChannel::SendPacketRaw(const void *data, size_t len, bool RTCP) 4046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4047fb648da2b9d33e8641c88a7f0559508539104b6dwu@webrtc.org CriticalSectionScoped cs(&_callbackCritSect); 4048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (_transportPtr == NULL) 4049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return -1; 4051470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4052470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (!RTCP) 4053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendPacket(_channelId, data, len); 4055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return _transportPtr->SendRTCPPacket(_channelId, data, len); 4059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40621de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org// Called for incoming RTP packets after successful RTP header parsing. 40631de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.orgvoid Channel::UpdatePacketDelay(uint32_t rtp_timestamp, 40641de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t sequence_number) { 40651de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId), 40661de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)", 40671de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org rtp_timestamp, sequence_number); 4068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40691de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Get frequency of last received payload 407094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int rtp_receive_frequency = GetPlayoutFrequency(); 4071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4072e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org // Update the least required delay. 4073eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org least_required_delay_ms_ = audio_coding_->LeastRequiredDelayMs(); 4074e46c8d387587ba148e229a7bb18f1cc0708a2a87turaj@webrtc.org 4075167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for 4076167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org // every incoming packet. 4077167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org uint32_t timestamp_diff_ms = (rtp_timestamp - 4078167b6dfc73fc2f4c47713bcbd89b58c52612983bturaj@webrtc.org jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000); 4079d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) || 4080d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) { 4081d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP 4082d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // timestamp, the resulting difference is negative, but is set to zero. 4083d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // This can happen when a network glitch causes a packet to arrive late, 4084d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org // and during long comfort noise periods with clock drift. 4085d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org timestamp_diff_ms = 0; 4086d66929995ff62e92c6cb5177d059e85b902fd388henrik.lundin@webrtc.org } 4087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40881de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) / 40891de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org (rtp_receive_frequency / 1000); 4090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40911de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _previousTimestamp = rtp_timestamp; 4092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 40931de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (timestamp_diff_ms == 0) return; 40941de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 40951de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (packet_delay_ms >= 10 && packet_delay_ms <= 60) { 40961de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _recPacketDelayMs = packet_delay_ms; 40971de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 40981de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 40991de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org if (_average_jitter_buffer_delay_us == 0) { 41001de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000; 41011de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org return; 41021de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org } 41031de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 41041de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // Filter average delay value using exponential filter (alpha is 41051de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces 41061de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // risk of rounding error) and compensate for it in GetDelayEstimate() 41071de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org // later. 41081de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 + 41091de01354e68da71bc62c81af17afeac8ed374a18pwestin@webrtc.org 1000 * timestamp_diff_ms + 500) / 8; 4110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid 4113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comChannel::RegisterReceiveCodecsToRTPModule() 4114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{ 4115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId), 4116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule()"); 4117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4119470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com CodecInst codec; 41206141e13873d0fdea626de08dfec2efa2c9171c76pbos@webrtc.org const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs(); 4121470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 4122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com for (int idx = 0; idx < nSupportedCodecs; idx++) 4123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Open up the RTP/RTCP receiver for all supported codecs 4125eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if ((audio_coding_->Codec(idx, &codec) == -1) || 4126822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (rtp_receiver_->RegisterReceivePayload( 4127822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plname, 4128822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.pltype, 4129822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.plfreq, 4130822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org codec.channels, 4131822fbd8b68ffdb481b9557e2950ae8d6657c8ce6wu@webrtc.org (codec.rate < 0) ? 0 : codec.rate) == -1)) 4132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 4134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceWarning, 4135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 4136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() unable" 4138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com " to register %s (%d/%d/%d/%d) to RTP/RTCP receiver", 4139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 4140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 4141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com else 4143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com { 4144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com WEBRTC_TRACE( 4145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceInfo, 4146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com kTraceVoice, 4147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com VoEId(_instanceId, _channelId), 4148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "Channel::RegisterReceiveCodecsToRTPModule() %s " 4149fcd12b3b7d7e92d6f8cdfdf8277808ae52a07c36wu@webrtc.org "(%d/%d/%d/%d) has been added to the RTP/RTCP " 4150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com "receiver", 4151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.plname, codec.pltype, codec.plfreq, 4152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com codec.channels, codec.rate); 4153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 4155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 4156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41578c8ad85c5d70c38cea82f5b17794a4e7ab4cf531turaj@webrtc.org// Assuming this method is called with valid payload type. 415842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.orgint Channel::SetRedPayloadType(int red_payload_type) { 415942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org CodecInst codec; 416042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org bool found_red = false; 416142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 416242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org // Get default RED settings from the ACM database 416342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org const int num_codecs = AudioCodingModule::NumberOfCodecs(); 416442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org for (int idx = 0; idx < num_codecs; idx++) { 4165eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org audio_coding_->Codec(idx, &codec); 416642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!STR_CASE_CMP(codec.plname, "RED")) { 416742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org found_red = true; 416842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org break; 416942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 417042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 417142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 417242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (!found_red) { 417342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 417442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_CODEC_ERROR, kTraceError, 417542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED is not supported"); 417642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 417742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 417842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 41799d532fd2752290e85aa804f29ab9aa6c017c9208turaj@webrtc.org codec.pltype = red_payload_type; 4180eb524d997b877ba9b0bcaf8c85eae52bd40c37e3andrew@webrtc.org if (audio_coding_->RegisterSendCodec(codec) < 0) { 418142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 418242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_AUDIO_CODING_MODULE_ERROR, kTraceError, 418342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in ACM module failed"); 418442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 418542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 418642259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 418742259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) { 418842259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org _engineStatisticsPtr->SetLastError( 418942259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org VE_RTP_RTCP_MODULE_ERROR, kTraceError, 419042259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org "SetRedPayloadType() RED registration in RTP/RTCP module failed"); 419142259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return -1; 419242259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org } 419342259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org return 0; 419442259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org} 419542259e7ebc7126f5a7036940fcab65b3f8d2af38turaj@webrtc.org 4196ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.orgint Channel::SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, 4197ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org unsigned char id) { 4198ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org int error = 0; 4199ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type); 4200ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org if (enable) { 4201ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(type, id); 4202ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org } 4203ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org return error; 4204ebdb0e3ad0a787bee066d12cdcd115a38b0a10d1wu@webrtc.org} 4205c1a40a7b68a8d253b0ba32b89f3126931eeaeab3minyue@webrtc.org 420694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.orgint32_t Channel::GetPlayoutFrequency() { 420794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org int32_t playout_frequency = audio_coding_->PlayoutFrequency(); 420894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org CodecInst current_recive_codec; 420994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (audio_coding_->ReceiveCodec(¤t_recive_codec) == 0) { 421094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org if (STR_CASE_CMP("G722", current_recive_codec.plname) == 0) { 421194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // Even though the actual sampling rate for G.722 audio is 421294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // 16,000 Hz, the RTP clock rate for the G722 payload format is 421394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // 8,000 Hz because that value was erroneously assigned in 421494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // RFC 1890 and must remain unchanged for backward compatibility. 421594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org playout_frequency = 8000; 421694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } else if (STR_CASE_CMP("opus", current_recive_codec.plname) == 0) { 421794454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // We are resampling Opus internally to 32,000 Hz until all our 421894454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // DSP routines can operate at 48,000 Hz, but the RTP clock 421994454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // rate for the Opus payload format is standardized to 48,000 Hz, 422094454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org // because that is the maximum supported decoding sampling rate. 422194454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org playout_frequency = 48000; 422294454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 422394454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org } 422494454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org return playout_frequency; 422594454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org} 422694454b71adc37e15fd3f5a5fc432063f05caabcbwu@webrtc.org 422716825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.orgint64_t Channel::GetRTT() const { 42282b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org RTCPMethod method = _rtpRtcpModule->RTCP(); 42292b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (method == kRtcpOff) { 42302b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org return 0; 42312b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 42322b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org std::vector<RTCPReportBlock> report_blocks; 42332b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org _rtpRtcpModule->RemoteRTCPStat(&report_blocks); 42342b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (report_blocks.empty()) { 42352b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org return 0; 42362b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 42372b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org 42382b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org uint32_t remoteSSRC = rtp_receiver_->SSRC(); 42392b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin(); 42402b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org for (; it != report_blocks.end(); ++it) { 42412b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (it->remoteSSRC == remoteSSRC) 42422b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org break; 42432b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 42442b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (it == report_blocks.end()) { 42452b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // We have not received packets with SSRC matching the report blocks. 42462b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // To calculate RTT we try with the SSRC of the first report block. 42472b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // This is very important for send-only channels where we don't know 42482b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org // the SSRC of the other end. 42492b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org remoteSSRC = report_blocks[0].remoteSSRC; 42502b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 425116825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t rtt = 0; 425216825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t avg_rtt = 0; 425316825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t max_rtt= 0; 425416825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org int64_t min_rtt = 0; 42552b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) 42562b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org != 0) { 42572b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org return 0; 42582b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org } 425916825b1a828bb4ff40f7682040e43a239b7b8ca3pkasting@chromium.org return rtt; 42602b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org} 42612b58a4433f16c510d56b1d16d2e3bb882b184861minyue@webrtc.org 4262d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace voe 4263d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org} // namespace webrtc 4264