LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/voice_engine - channel.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1599 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 196 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/voice_engine/channel.h"
      12             : 
      13             : #include <algorithm>
      14             : #include <utility>
      15             : 
      16             : #include "webrtc/audio/utility/audio_frame_operations.h"
      17             : #include "webrtc/base/array_view.h"
      18             : #include "webrtc/base/checks.h"
      19             : #include "webrtc/base/criticalsection.h"
      20             : #include "webrtc/base/format_macros.h"
      21             : #include "webrtc/base/logging.h"
      22             : #include "webrtc/base/rate_limiter.h"
      23             : #include "webrtc/base/thread_checker.h"
      24             : #include "webrtc/base/timeutils.h"
      25             : #include "webrtc/config.h"
      26             : #include "webrtc/logging/rtc_event_log/rtc_event_log.h"
      27             : #include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
      28             : #include "webrtc/modules/audio_device/include/audio_device.h"
      29             : #include "webrtc/modules/audio_processing/include/audio_processing.h"
      30             : #include "webrtc/modules/include/module_common_types.h"
      31             : #include "webrtc/modules/pacing/packet_router.h"
      32             : #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
      33             : #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
      34             : #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
      35             : #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
      36             : #include "webrtc/modules/utility/include/process_thread.h"
      37             : #include "webrtc/system_wrappers/include/trace.h"
      38             : #include "webrtc/voice_engine/include/voe_external_media.h"
      39             : #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
      40             : #include "webrtc/voice_engine/output_mixer.h"
      41             : #include "webrtc/voice_engine/statistics.h"
      42             : #include "webrtc/voice_engine/transmit_mixer.h"
      43             : #include "webrtc/voice_engine/utility.h"
      44             : 
      45             : namespace webrtc {
      46             : namespace voe {
      47             : 
      48             : namespace {
      49             : 
      50             : constexpr int64_t kMaxRetransmissionWindowMs = 1000;
      51             : constexpr int64_t kMinRetransmissionWindowMs = 30;
      52             : 
      53             : }  // namespace
      54             : 
      55             : const int kTelephoneEventAttenuationdB = 10;
      56             : 
      57           0 : class RtcEventLogProxy final : public webrtc::RtcEventLog {
      58             :  public:
      59           0 :   RtcEventLogProxy() : event_log_(nullptr) {}
      60             : 
      61           0 :   bool StartLogging(const std::string& file_name,
      62             :                     int64_t max_size_bytes) override {
      63           0 :     RTC_NOTREACHED();
      64           0 :     return false;
      65             :   }
      66             : 
      67           0 :   bool StartLogging(rtc::PlatformFile log_file,
      68             :                     int64_t max_size_bytes) override {
      69           0 :     RTC_NOTREACHED();
      70           0 :     return false;
      71             :   }
      72             : 
      73           0 :   void StopLogging() override { RTC_NOTREACHED(); }
      74             : 
      75           0 :   void LogVideoReceiveStreamConfig(
      76             :       const webrtc::VideoReceiveStream::Config& config) override {
      77           0 :     rtc::CritScope lock(&crit_);
      78           0 :     if (event_log_) {
      79           0 :       event_log_->LogVideoReceiveStreamConfig(config);
      80             :     }
      81           0 :   }
      82             : 
      83           0 :   void LogVideoSendStreamConfig(
      84             :       const webrtc::VideoSendStream::Config& config) override {
      85           0 :     rtc::CritScope lock(&crit_);
      86           0 :     if (event_log_) {
      87           0 :       event_log_->LogVideoSendStreamConfig(config);
      88             :     }
      89           0 :   }
      90             : 
      91           0 :   void LogAudioReceiveStreamConfig(
      92             :       const webrtc::AudioReceiveStream::Config& config) override {
      93           0 :     rtc::CritScope lock(&crit_);
      94           0 :     if (event_log_) {
      95           0 :       event_log_->LogAudioReceiveStreamConfig(config);
      96             :     }
      97           0 :   }
      98             : 
      99           0 :   void LogAudioSendStreamConfig(
     100             :       const webrtc::AudioSendStream::Config& config) override {
     101           0 :     rtc::CritScope lock(&crit_);
     102           0 :     if (event_log_) {
     103           0 :       event_log_->LogAudioSendStreamConfig(config);
     104             :     }
     105           0 :   }
     106             : 
     107           0 :   void LogRtpHeader(webrtc::PacketDirection direction,
     108             :                     webrtc::MediaType media_type,
     109             :                     const uint8_t* header,
     110             :                     size_t packet_length) override {
     111           0 :     rtc::CritScope lock(&crit_);
     112           0 :     if (event_log_) {
     113           0 :       event_log_->LogRtpHeader(direction, media_type, header, packet_length);
     114             :     }
     115           0 :   }
     116             : 
     117           0 :   void LogRtcpPacket(webrtc::PacketDirection direction,
     118             :                      webrtc::MediaType media_type,
     119             :                      const uint8_t* packet,
     120             :                      size_t length) override {
     121           0 :     rtc::CritScope lock(&crit_);
     122           0 :     if (event_log_) {
     123           0 :       event_log_->LogRtcpPacket(direction, media_type, packet, length);
     124             :     }
     125           0 :   }
     126             : 
     127           0 :   void LogAudioPlayout(uint32_t ssrc) override {
     128           0 :     rtc::CritScope lock(&crit_);
     129           0 :     if (event_log_) {
     130           0 :       event_log_->LogAudioPlayout(ssrc);
     131             :     }
     132           0 :   }
     133             : 
     134           0 :   void LogBwePacketLossEvent(int32_t bitrate,
     135             :                              uint8_t fraction_loss,
     136             :                              int32_t total_packets) override {
     137           0 :     rtc::CritScope lock(&crit_);
     138           0 :     if (event_log_) {
     139           0 :       event_log_->LogBwePacketLossEvent(bitrate, fraction_loss, total_packets);
     140             :     }
     141           0 :   }
     142             : 
     143           0 :   void SetEventLog(RtcEventLog* event_log) {
     144           0 :     rtc::CritScope lock(&crit_);
     145           0 :     event_log_ = event_log;
     146           0 :   }
     147             : 
     148             :  private:
     149             :   rtc::CriticalSection crit_;
     150             :   RtcEventLog* event_log_ GUARDED_BY(crit_);
     151             :   RTC_DISALLOW_COPY_AND_ASSIGN(RtcEventLogProxy);
     152             : };
     153             : 
     154           0 : class RtcpRttStatsProxy final : public RtcpRttStats {
     155             :  public:
     156           0 :   RtcpRttStatsProxy() : rtcp_rtt_stats_(nullptr) {}
     157             : 
     158           0 :   void OnRttUpdate(int64_t rtt) override {
     159           0 :     rtc::CritScope lock(&crit_);
     160           0 :     if (rtcp_rtt_stats_)
     161           0 :       rtcp_rtt_stats_->OnRttUpdate(rtt);
     162           0 :   }
     163             : 
     164           0 :   int64_t LastProcessedRtt() const override {
     165           0 :     rtc::CritScope lock(&crit_);
     166           0 :     if (!rtcp_rtt_stats_)
     167           0 :       return 0;
     168           0 :     return rtcp_rtt_stats_->LastProcessedRtt();
     169             :   }
     170             : 
     171           0 :   void SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats) {
     172           0 :     rtc::CritScope lock(&crit_);
     173           0 :     rtcp_rtt_stats_ = rtcp_rtt_stats;
     174           0 :   }
     175             : 
     176             :  private:
     177             :   rtc::CriticalSection crit_;
     178             :   RtcpRttStats* rtcp_rtt_stats_ GUARDED_BY(crit_);
     179             :   RTC_DISALLOW_COPY_AND_ASSIGN(RtcpRttStatsProxy);
     180             : };
     181             : 
     182           0 : class TransportFeedbackProxy : public TransportFeedbackObserver {
     183             :  public:
     184           0 :   TransportFeedbackProxy() : feedback_observer_(nullptr) {
     185           0 :     pacer_thread_.DetachFromThread();
     186           0 :     network_thread_.DetachFromThread();
     187           0 :   }
     188             : 
     189           0 :   void SetTransportFeedbackObserver(
     190             :       TransportFeedbackObserver* feedback_observer) {
     191           0 :     RTC_DCHECK(thread_checker_.CalledOnValidThread());
     192           0 :     rtc::CritScope lock(&crit_);
     193           0 :     feedback_observer_ = feedback_observer;
     194           0 :   }
     195             : 
     196             :   // Implements TransportFeedbackObserver.
     197           0 :   void AddPacket(uint16_t sequence_number,
     198             :                  size_t length,
     199             :                  int probe_cluster_id) override {
     200           0 :     RTC_DCHECK(pacer_thread_.CalledOnValidThread());
     201           0 :     rtc::CritScope lock(&crit_);
     202           0 :     if (feedback_observer_)
     203           0 :       feedback_observer_->AddPacket(sequence_number, length, probe_cluster_id);
     204           0 :   }
     205           0 :   void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override {
     206           0 :     RTC_DCHECK(network_thread_.CalledOnValidThread());
     207           0 :     rtc::CritScope lock(&crit_);
     208           0 :     if (feedback_observer_)
     209           0 :       feedback_observer_->OnTransportFeedback(feedback);
     210           0 :   }
     211           0 :   std::vector<PacketInfo> GetTransportFeedbackVector() const override {
     212           0 :     RTC_NOTREACHED();
     213           0 :     return std::vector<PacketInfo>();
     214             :   }
     215             : 
     216             :  private:
     217             :   rtc::CriticalSection crit_;
     218             :   rtc::ThreadChecker thread_checker_;
     219             :   rtc::ThreadChecker pacer_thread_;
     220             :   rtc::ThreadChecker network_thread_;
     221             :   TransportFeedbackObserver* feedback_observer_ GUARDED_BY(&crit_);
     222             : };
     223             : 
     224           0 : class TransportSequenceNumberProxy : public TransportSequenceNumberAllocator {
     225             :  public:
     226           0 :   TransportSequenceNumberProxy() : seq_num_allocator_(nullptr) {
     227           0 :     pacer_thread_.DetachFromThread();
     228           0 :   }
     229             : 
     230           0 :   void SetSequenceNumberAllocator(
     231             :       TransportSequenceNumberAllocator* seq_num_allocator) {
     232           0 :     RTC_DCHECK(thread_checker_.CalledOnValidThread());
     233           0 :     rtc::CritScope lock(&crit_);
     234           0 :     seq_num_allocator_ = seq_num_allocator;
     235           0 :   }
     236             : 
     237             :   // Implements TransportSequenceNumberAllocator.
     238           0 :   uint16_t AllocateSequenceNumber() override {
     239           0 :     RTC_DCHECK(pacer_thread_.CalledOnValidThread());
     240           0 :     rtc::CritScope lock(&crit_);
     241           0 :     if (!seq_num_allocator_)
     242           0 :       return 0;
     243           0 :     return seq_num_allocator_->AllocateSequenceNumber();
     244             :   }
     245             : 
     246             :  private:
     247             :   rtc::CriticalSection crit_;
     248             :   rtc::ThreadChecker thread_checker_;
     249             :   rtc::ThreadChecker pacer_thread_;
     250             :   TransportSequenceNumberAllocator* seq_num_allocator_ GUARDED_BY(&crit_);
     251             : };
     252             : 
     253           0 : class RtpPacketSenderProxy : public RtpPacketSender {
     254             :  public:
     255           0 :   RtpPacketSenderProxy() : rtp_packet_sender_(nullptr) {}
     256             : 
     257           0 :   void SetPacketSender(RtpPacketSender* rtp_packet_sender) {
     258           0 :     RTC_DCHECK(thread_checker_.CalledOnValidThread());
     259           0 :     rtc::CritScope lock(&crit_);
     260           0 :     rtp_packet_sender_ = rtp_packet_sender;
     261           0 :   }
     262             : 
     263             :   // Implements RtpPacketSender.
     264           0 :   void InsertPacket(Priority priority,
     265             :                     uint32_t ssrc,
     266             :                     uint16_t sequence_number,
     267             :                     int64_t capture_time_ms,
     268             :                     size_t bytes,
     269             :                     bool retransmission) override {
     270           0 :     rtc::CritScope lock(&crit_);
     271           0 :     if (rtp_packet_sender_) {
     272           0 :       rtp_packet_sender_->InsertPacket(priority, ssrc, sequence_number,
     273           0 :                                        capture_time_ms, bytes, retransmission);
     274             :     }
     275           0 :   }
     276             : 
     277             :  private:
     278             :   rtc::ThreadChecker thread_checker_;
     279             :   rtc::CriticalSection crit_;
     280             :   RtpPacketSender* rtp_packet_sender_ GUARDED_BY(&crit_);
     281             : };
     282             : 
     283             : // Extend the default RTCP statistics struct with max_jitter, defined as the
     284             : // maximum jitter value seen in an RTCP report block.
     285             : struct ChannelStatistics : public RtcpStatistics {
     286           0 :   ChannelStatistics() : rtcp(), max_jitter(0) {}
     287             : 
     288             :   RtcpStatistics rtcp;
     289             :   uint32_t max_jitter;
     290             : };
     291             : 
     292             : // Statistics callback, called at each generation of a new RTCP report block.
     293             : class StatisticsProxy : public RtcpStatisticsCallback,
     294             :    public RtcpPacketTypeCounterObserver {
     295             :  public:
     296           0 :   StatisticsProxy(uint32_t ssrc) : ssrc_(ssrc) {}
     297           0 :   virtual ~StatisticsProxy() {}
     298             : 
     299           0 :   void StatisticsUpdated(const RtcpStatistics& statistics,
     300             :                          uint32_t ssrc) override {
     301           0 :     rtc::CritScope cs(&stats_lock_);
     302           0 :     if (ssrc != ssrc_)
     303           0 :       return;
     304             : 
     305           0 :     stats_.rtcp = statistics;
     306           0 :     if (statistics.jitter > stats_.max_jitter) {
     307           0 :       stats_.max_jitter = statistics.jitter;
     308             :     }
     309             :   }
     310             : 
     311           0 :   void CNameChanged(const char* cname, uint32_t ssrc) override {}
     312             : 
     313           0 :   void SetSSRC(uint32_t ssrc) {
     314           0 :     rtc::CritScope cs(&stats_lock_);
     315           0 :     ssrc_ = ssrc;
     316           0 :   }
     317             : 
     318           0 :   ChannelStatistics GetStats() {
     319           0 :     rtc::CritScope cs(&stats_lock_);
     320           0 :     return stats_;
     321             :   }
     322             : 
     323           0 :   void RtcpPacketTypesCounterUpdated(uint32_t ssrc,
     324             :       const RtcpPacketTypeCounter& packet_counter) override {
     325           0 :     rtc::CritScope cs(&stats_lock_);
     326           0 :     if (ssrc != ssrc_) {
     327           0 :       return;
     328             :     }
     329           0 :     packet_counter_ = packet_counter;
     330             :  };
     331             : 
     332           0 :  void GetPacketTypeCounter(RtcpPacketTypeCounter& aPacketTypeCounter) {
     333           0 :     rtc::CritScope cs(&stats_lock_);
     334           0 :     aPacketTypeCounter = packet_counter_;
     335           0 :  }
     336             : 
     337             :  private:
     338             :   // StatisticsUpdated calls are triggered from threads in the RTP module,
     339             :   // while GetStats calls can be triggered from the public voice engine API,
     340             :   // hence synchronization is needed.
     341             :   rtc::CriticalSection stats_lock_;
     342             :   uint32_t ssrc_;
     343             :   ChannelStatistics stats_;
     344             :   RtcpPacketTypeCounter packet_counter_;
     345             : };
     346             : 
     347             : class VoERtcpObserver : public RtcpBandwidthObserver {
     348             :  public:
     349           0 :   explicit VoERtcpObserver(Channel* owner) : owner_(owner) {}
     350           0 :   virtual ~VoERtcpObserver() {}
     351             : 
     352           0 :   void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
     353             :     // Not used for Voice Engine.
     354           0 :   }
     355             : 
     356           0 :   void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
     357             :                                     int64_t rtt,
     358             :                                     int64_t now_ms) override {
     359             :     // TODO(mflodman): Do we need to aggregate reports here or can we jut send
     360             :     // what we get? I.e. do we ever get multiple reports bundled into one RTCP
     361             :     // report for VoiceEngine?
     362           0 :     if (report_blocks.empty())
     363           0 :       return;
     364             : 
     365           0 :     int fraction_lost_aggregate = 0;
     366           0 :     int total_number_of_packets = 0;
     367             : 
     368             :     // If receiving multiple report blocks, calculate the weighted average based
     369             :     // on the number of packets a report refers to.
     370           0 :     for (ReportBlockList::const_iterator block_it = report_blocks.begin();
     371           0 :          block_it != report_blocks.end(); ++block_it) {
     372             :       // Find the previous extended high sequence number for this remote SSRC,
     373             :       // to calculate the number of RTP packets this report refers to. Ignore if
     374             :       // we haven't seen this SSRC before.
     375             :       std::map<uint32_t, uint32_t>::iterator seq_num_it =
     376           0 :           extended_max_sequence_number_.find(block_it->sourceSSRC);
     377           0 :       int number_of_packets = 0;
     378           0 :       if (seq_num_it != extended_max_sequence_number_.end()) {
     379           0 :         number_of_packets = block_it->extendedHighSeqNum - seq_num_it->second;
     380             :       }
     381           0 :       fraction_lost_aggregate += number_of_packets * block_it->fractionLost;
     382           0 :       total_number_of_packets += number_of_packets;
     383             : 
     384           0 :       extended_max_sequence_number_[block_it->sourceSSRC] =
     385           0 :           block_it->extendedHighSeqNum;
     386             :     }
     387           0 :     int weighted_fraction_lost = 0;
     388           0 :     if (total_number_of_packets > 0) {
     389           0 :       weighted_fraction_lost =
     390           0 :           (fraction_lost_aggregate + total_number_of_packets / 2) /
     391             :           total_number_of_packets;
     392             :     }
     393           0 :     owner_->OnIncomingFractionLoss(weighted_fraction_lost);
     394             :   }
     395             : 
     396             :  private:
     397             :   Channel* owner_;
     398             :   // Maps remote side ssrc to extended highest sequence number received.
     399             :   std::map<uint32_t, uint32_t> extended_max_sequence_number_;
     400             : };
     401             : 
     402           0 : int32_t Channel::SendData(FrameType frameType,
     403             :                           uint8_t payloadType,
     404             :                           uint32_t timeStamp,
     405             :                           const uint8_t* payloadData,
     406             :                           size_t payloadSize,
     407             :                           const RTPFragmentationHeader* fragmentation) {
     408             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     409             :                "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u,"
     410             :                " payloadSize=%" PRIuS ", fragmentation=0x%x)",
     411             :                frameType, payloadType, timeStamp, payloadSize, fragmentation);
     412             : 
     413           0 :   if (_includeAudioLevelIndication) {
     414             :     // Store current audio level in the RTP/RTCP module.
     415             :     // The level will be used in combination with voice-activity state
     416             :     // (frameType) to add an RTP header extension
     417           0 :     _rtpRtcpModule->SetAudioLevel(rms_level_.Average());
     418             :   }
     419             : 
     420             :   // Push data from ACM to RTP/RTCP-module to deliver audio frame for
     421             :   // packetization.
     422             :   // This call will trigger Transport::SendPacket() from the RTP/RTCP module.
     423           0 :   if (!_rtpRtcpModule->SendOutgoingData(
     424             :           (FrameType&)frameType, payloadType, timeStamp,
     425             :           // Leaving the time when this frame was
     426             :           // received from the capture device as
     427             :           // undefined for voice for now.
     428           0 :           -1, payloadData, payloadSize, fragmentation, nullptr, nullptr)) {
     429           0 :     _engineStatisticsPtr->SetLastError(
     430             :         VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
     431           0 :         "Channel::SendData() failed to send data to RTP/RTCP module");
     432           0 :     return -1;
     433             :   }
     434             : 
     435           0 :   _lastLocalTimeStamp = timeStamp;
     436           0 :   _lastPayloadType = payloadType;
     437             : 
     438           0 :   return 0;
     439             : }
     440             : 
     441           0 : int32_t Channel::InFrameType(FrameType frame_type) {
     442             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     443             :                "Channel::InFrameType(frame_type=%d)", frame_type);
     444             : 
     445           0 :   rtc::CritScope cs(&_callbackCritSect);
     446           0 :   _sendFrameType = (frame_type == kAudioFrameSpeech);
     447           0 :   return 0;
     448             : }
     449             : 
     450           0 : bool Channel::SendRtp(const uint8_t* data,
     451             :                       size_t len,
     452             :                       const PacketOptions& options) {
     453             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     454             :                "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len);
     455             : 
     456           0 :   rtc::CritScope cs(&_callbackCritSect);
     457             : 
     458           0 :   if (_transportPtr == NULL) {
     459             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
     460             :                  "Channel::SendPacket() failed to send RTP packet due to"
     461             :                  " invalid transport object");
     462           0 :     return false;
     463             :   }
     464             : 
     465           0 :   uint8_t* bufferToSendPtr = (uint8_t*)data;
     466           0 :   size_t bufferLength = len;
     467             : 
     468           0 :   if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength, options)) {
     469             :     std::string transport_name =
     470           0 :         _externalTransport ? "external transport" : "WebRtc sockets";
     471             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
     472             :                  "Channel::SendPacket() RTP transmission using %s failed",
     473             :                  transport_name.c_str());
     474           0 :     return false;
     475             :   }
     476           0 :   return true;
     477             : }
     478             : 
     479           0 : bool Channel::SendRtcp(const uint8_t* data, size_t len) {
     480             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     481             :                "Channel::SendRtcp(len=%" PRIuS ")", len);
     482             : 
     483           0 :   rtc::CritScope cs(&_callbackCritSect);
     484           0 :   if (_transportPtr == NULL) {
     485             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
     486             :                  "Channel::SendRtcp() failed to send RTCP packet"
     487             :                  " due to invalid transport object");
     488           0 :     return false;
     489             :   }
     490             : 
     491           0 :   uint8_t* bufferToSendPtr = (uint8_t*)data;
     492           0 :   size_t bufferLength = len;
     493             : 
     494           0 :   int n = _transportPtr->SendRtcp(bufferToSendPtr, bufferLength);
     495           0 :   if (n < 0) {
     496             :     std::string transport_name =
     497           0 :         _externalTransport ? "external transport" : "WebRtc sockets";
     498             :     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     499             :                  "Channel::SendRtcp() transmission using %s failed",
     500             :                  transport_name.c_str());
     501           0 :     return false;
     502             :   }
     503           0 :   return true;
     504             : }
     505             : 
     506           0 : void Channel::OnIncomingSSRCChanged(uint32_t ssrc) {
     507             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     508             :                "Channel::OnIncomingSSRCChanged(SSRC=%d)", ssrc);
     509             : 
     510             :   // Update ssrc so that NTP for AV sync can be updated.
     511           0 :   _rtpRtcpModule->SetRemoteSSRC(ssrc);
     512             :   // Update stats proxy to receive stats for new ssrc
     513           0 :   statistics_proxy_->SetSSRC(ssrc);
     514           0 : }
     515             : 
     516           0 : void Channel::OnIncomingCSRCChanged(uint32_t CSRC, bool added) {
     517             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     518             :                "Channel::OnIncomingCSRCChanged(CSRC=%d, added=%d)", CSRC,
     519             :                added);
     520           0 : }
     521             : 
     522           0 : int32_t Channel::OnInitializeDecoder(
     523             :     int8_t payloadType,
     524             :     const char payloadName[RTP_PAYLOAD_NAME_SIZE],
     525             :     int frequency,
     526             :     size_t channels,
     527             :     uint32_t rate) {
     528             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     529             :                "Channel::OnInitializeDecoder(payloadType=%d, "
     530             :                "payloadName=%s, frequency=%u, channels=%" PRIuS ", rate=%u)",
     531             :                payloadType, payloadName, frequency, channels, rate);
     532             : 
     533           0 :   CodecInst receiveCodec = {0};
     534           0 :   CodecInst dummyCodec = {0};
     535             : 
     536           0 :   receiveCodec.pltype = payloadType;
     537           0 :   receiveCodec.plfreq = frequency;
     538           0 :   receiveCodec.channels = channels;
     539           0 :   receiveCodec.rate = rate;
     540           0 :   strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
     541             : 
     542           0 :   audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels);
     543           0 :   receiveCodec.pacsize = dummyCodec.pacsize;
     544             : 
     545             :   // Register the new codec to the ACM
     546           0 :   if (!audio_coding_->RegisterReceiveCodec(receiveCodec.pltype,
     547           0 :                                            CodecInstToSdp(receiveCodec))) {
     548             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
     549             :                  "Channel::OnInitializeDecoder() invalid codec ("
     550             :                  "pt=%d, name=%s) received - 1",
     551             :                  payloadType, payloadName);
     552           0 :     _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR);
     553           0 :     return -1;
     554             :   }
     555             : 
     556           0 :   return 0;
     557             : }
     558             : 
     559           0 : int32_t Channel::OnReceivedPayloadData(const uint8_t* payloadData,
     560             :                                        size_t payloadSize,
     561             :                                        const WebRtcRTPHeader* rtpHeader) {
     562             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     563             :                "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS
     564             :                ","
     565             :                " payloadType=%u, audioChannel=%" PRIuS ")",
     566             :                payloadSize, rtpHeader->header.payloadType,
     567             :                rtpHeader->type.Audio.channel);
     568             : 
     569           0 :   if (!channel_state_.Get().playing) {
     570             :     // Avoid inserting into NetEQ when we are not playing. Count the
     571             :     // packet as discarded.
     572             :     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     573             :                  "received packet is discarded since playing is not"
     574             :                  " activated");
     575           0 :     _numberOfDiscardedPackets++;
     576           0 :     return 0;
     577             :   }
     578             : 
     579             :   // Push the incoming payload (parsed and ready for decoding) into the ACM
     580           0 :   if (audio_coding_->IncomingPacket(payloadData, payloadSize, *rtpHeader) !=
     581             :       0) {
     582           0 :     _engineStatisticsPtr->SetLastError(
     583             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning,
     584           0 :         "Channel::OnReceivedPayloadData() unable to push data to the ACM");
     585           0 :     return -1;
     586             :   }
     587             : 
     588           0 :   int64_t round_trip_time = 0;
     589           0 :   _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, NULL, NULL,
     590           0 :                       NULL);
     591             : 
     592           0 :   std::vector<uint16_t> nack_list = audio_coding_->GetNackList(round_trip_time);
     593           0 :   if (!nack_list.empty()) {
     594             :     // Can't use nack_list.data() since it's not supported by all
     595             :     // compilers.
     596           0 :     ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size()));
     597             :   }
     598           0 :   return 0;
     599             : }
     600             : 
     601           0 : bool Channel::OnRecoveredPacket(const uint8_t* rtp_packet,
     602             :                                 size_t rtp_packet_length) {
     603           0 :   RTPHeader header;
     604           0 :   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
     605             :     WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVoice, _channelId,
     606             :                  "IncomingPacket invalid RTP header");
     607           0 :     return false;
     608             :   }
     609           0 :   header.payload_type_frequency =
     610           0 :       rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
     611           0 :   if (header.payload_type_frequency < 0)
     612           0 :     return false;
     613           0 :   return ReceivePacket(rtp_packet, rtp_packet_length, header, false);
     614             : }
     615             : 
     616           0 : MixerParticipant::AudioFrameInfo Channel::GetAudioFrameWithMuted(
     617             :     int32_t id,
     618             :     AudioFrame* audioFrame) {
     619             :   unsigned int ssrc;
     620           0 :   RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0);
     621           0 :   event_log_proxy_->LogAudioPlayout(ssrc);
     622             :   // Get 10ms raw PCM data from the ACM (mixer limits output frequency)
     623             :   bool muted;
     624           0 :   if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_, audioFrame,
     625           0 :                                      &muted) == -1) {
     626             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
     627             :                  "Channel::GetAudioFrame() PlayoutData10Ms() failed!");
     628             :     // In all likelihood, the audio in this frame is garbage. We return an
     629             :     // error so that the audio mixer module doesn't add it to the mix. As
     630             :     // a result, it won't be played out and the actions skipped here are
     631             :     // irrelevant.
     632           0 :     return MixerParticipant::AudioFrameInfo::kError;
     633             :   }
     634             : 
     635           0 :   if (muted) {
     636             :     // TODO(henrik.lundin): We should be able to do better than this. But we
     637             :     // will have to go through all the cases below where the audio samples may
     638             :     // be used, and handle the muted case in some way.
     639           0 :     AudioFrameOperations::Mute(audioFrame);
     640             :   }
     641             : 
     642             :   // Convert module ID to internal VoE channel ID
     643           0 :   audioFrame->id_ = VoEChannelId(audioFrame->id_);
     644             :   // Store speech type for dead-or-alive detection
     645           0 :   _outputSpeechType = audioFrame->speech_type_;
     646             : 
     647           0 :   ChannelState::State state = channel_state_.Get();
     648             : 
     649             :   {
     650             :     // Pass the audio buffers to an optional sink callback, before applying
     651             :     // scaling/panning, as that applies to the mix operation.
     652             :     // External recipients of the audio (e.g. via AudioTrack), will do their
     653             :     // own mixing/dynamic processing.
     654           0 :     rtc::CritScope cs(&_callbackCritSect);
     655           0 :     if (audio_sink_) {
     656             :       AudioSinkInterface::Data data(
     657             :           &audioFrame->data_[0], audioFrame->samples_per_channel_,
     658             :           audioFrame->sample_rate_hz_, audioFrame->num_channels_,
     659           0 :           audioFrame->timestamp_);
     660           0 :       audio_sink_->OnData(data);
     661             :     }
     662             :   }
     663             : 
     664           0 :   float output_gain = 1.0f;
     665           0 :   float left_pan = 1.0f;
     666           0 :   float right_pan = 1.0f;
     667             :   {
     668           0 :     rtc::CritScope cs(&volume_settings_critsect_);
     669           0 :     output_gain = _outputGain;
     670           0 :     left_pan = _panLeft;
     671           0 :     right_pan = _panRight;
     672             :   }
     673             : 
     674             :   // Output volume scaling
     675           0 :   if (output_gain < 0.99f || output_gain > 1.01f) {
     676           0 :     AudioFrameOperations::ScaleWithSat(output_gain, *audioFrame);
     677             :   }
     678             : 
     679             :   // Scale left and/or right channel(s) if stereo and master balance is
     680             :   // active
     681             : 
     682           0 :   if (left_pan != 1.0f || right_pan != 1.0f) {
     683           0 :     if (audioFrame->num_channels_ == 1) {
     684             :       // Emulate stereo mode since panning is active.
     685             :       // The mono signal is copied to both left and right channels here.
     686           0 :       AudioFrameOperations::MonoToStereo(audioFrame);
     687             :     }
     688             :     // For true stereo mode (when we are receiving a stereo signal), no
     689             :     // action is needed.
     690             : 
     691             :     // Do the panning operation (the audio frame contains stereo at this
     692             :     // stage)
     693           0 :     AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame);
     694             :   }
     695             : 
     696             :   // Mix decoded PCM output with file if file mixing is enabled
     697           0 :   if (state.output_file_playing) {
     698           0 :     MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_);
     699           0 :     muted = false;  // We may have added non-zero samples.
     700             :   }
     701             : 
     702             :   // External media
     703           0 :   if (_outputExternalMedia) {
     704           0 :     rtc::CritScope cs(&_callbackCritSect);
     705           0 :     const bool isStereo = (audioFrame->num_channels_ == 2);
     706           0 :     if (_outputExternalMediaCallbackPtr) {
     707           0 :       _outputExternalMediaCallbackPtr->Process(
     708             :           _channelId, kPlaybackPerChannel, (int16_t*)audioFrame->data_,
     709             :           audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_,
     710           0 :           isStereo);
     711             :     }
     712             :   }
     713             : 
     714             :   // Record playout if enabled
     715             :   {
     716           0 :     rtc::CritScope cs(&_fileCritSect);
     717             : 
     718           0 :     if (_outputFileRecording && output_file_recorder_) {
     719           0 :       output_file_recorder_->RecordAudioToFile(*audioFrame);
     720             :     }
     721             :   }
     722             : 
     723             :   // Measure audio level (0-9)
     724             :   // TODO(henrik.lundin) Use the |muted| information here too.
     725           0 :   _outputAudioLevel.ComputeLevel(*audioFrame);
     726             : 
     727           0 :   if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) {
     728             :     // The first frame with a valid rtp timestamp.
     729           0 :     capture_start_rtp_time_stamp_ = audioFrame->timestamp_;
     730             :   }
     731             : 
     732           0 :   if (capture_start_rtp_time_stamp_ >= 0) {
     733             :     // audioFrame.timestamp_ should be valid from now on.
     734             : 
     735             :     // Compute elapsed time.
     736             :     int64_t unwrap_timestamp =
     737           0 :         rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_);
     738           0 :     audioFrame->elapsed_time_ms_ =
     739           0 :         (unwrap_timestamp - capture_start_rtp_time_stamp_) /
     740           0 :         (GetRtpTimestampRateHz() / 1000);
     741             : 
     742             :     {
     743           0 :       rtc::CritScope lock(&ts_stats_lock_);
     744             :       // Compute ntp time.
     745           0 :       audioFrame->ntp_time_ms_ =
     746           0 :           ntp_estimator_.Estimate(audioFrame->timestamp_);
     747             :       // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received.
     748           0 :       if (audioFrame->ntp_time_ms_ > 0) {
     749             :         // Compute |capture_start_ntp_time_ms_| so that
     750             :         // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_|
     751           0 :         capture_start_ntp_time_ms_ =
     752           0 :             audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_;
     753             :       }
     754             :     }
     755             :   }
     756             : 
     757           0 :   return muted ? MixerParticipant::AudioFrameInfo::kMuted
     758           0 :                : MixerParticipant::AudioFrameInfo::kNormal;
     759             : }
     760             : 
     761           0 : AudioMixer::Source::AudioFrameInfo Channel::GetAudioFrameWithInfo(
     762             :     int sample_rate_hz,
     763             :     AudioFrame* audio_frame) {
     764           0 :   audio_frame->sample_rate_hz_ = sample_rate_hz;
     765             : 
     766           0 :   const auto frame_info = GetAudioFrameWithMuted(-1, audio_frame);
     767             : 
     768             :   using FrameInfo = AudioMixer::Source::AudioFrameInfo;
     769           0 :   FrameInfo new_audio_frame_info = FrameInfo::kError;
     770           0 :   switch (frame_info) {
     771             :     case MixerParticipant::AudioFrameInfo::kNormal:
     772           0 :       new_audio_frame_info = FrameInfo::kNormal;
     773           0 :       break;
     774             :     case MixerParticipant::AudioFrameInfo::kMuted:
     775           0 :       new_audio_frame_info = FrameInfo::kMuted;
     776           0 :       break;
     777             :     case MixerParticipant::AudioFrameInfo::kError:
     778           0 :       new_audio_frame_info = FrameInfo::kError;
     779           0 :       break;
     780             :   }
     781           0 :   return new_audio_frame_info;
     782             : }
     783             : 
     784           0 : int32_t Channel::NeededFrequency(int32_t id) const {
     785             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     786             :                "Channel::NeededFrequency(id=%d)", id);
     787             : 
     788           0 :   int highestNeeded = 0;
     789             : 
     790             :   // Determine highest needed receive frequency
     791           0 :   int32_t receiveFrequency = audio_coding_->ReceiveFrequency();
     792             : 
     793             :   // Return the bigger of playout and receive frequency in the ACM.
     794           0 :   if (audio_coding_->PlayoutFrequency() > receiveFrequency) {
     795           0 :     highestNeeded = audio_coding_->PlayoutFrequency();
     796             :   } else {
     797           0 :     highestNeeded = receiveFrequency;
     798             :   }
     799             : 
     800             :   // Special case, if we're playing a file on the playout side
     801             :   // we take that frequency into consideration as well
     802             :   // This is not needed on sending side, since the codec will
     803             :   // limit the spectrum anyway.
     804           0 :   if (channel_state_.Get().output_file_playing) {
     805           0 :     rtc::CritScope cs(&_fileCritSect);
     806           0 :     if (output_file_player_) {
     807           0 :       if (output_file_player_->Frequency() > highestNeeded) {
     808           0 :         highestNeeded = output_file_player_->Frequency();
     809             :       }
     810             :     }
     811             :   }
     812             : 
     813           0 :   return (highestNeeded);
     814             : }
     815             : 
     816           0 : int32_t Channel::CreateChannel(
     817             :     Channel*& channel,
     818             :     int32_t channelId,
     819             :     uint32_t instanceId,
     820             :     const VoEBase::ChannelConfig& config) {
     821             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId),
     822             :                "Channel::CreateChannel(channelId=%d, instanceId=%d)", channelId,
     823             :                instanceId);
     824             : 
     825           0 :   channel = new Channel(channelId, instanceId, config);
     826           0 :   if (channel == NULL) {
     827             :     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId, channelId),
     828             :                  "Channel::CreateChannel() unable to allocate memory for"
     829             :                  " channel");
     830           0 :     return -1;
     831             :   }
     832           0 :   return 0;
     833             : }
     834             : 
     835           0 : void Channel::PlayNotification(int32_t id, uint32_t durationMs) {
     836             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     837             :                "Channel::PlayNotification(id=%d, durationMs=%d)", id,
     838             :                durationMs);
     839             : 
     840             :   // Not implement yet
     841           0 : }
     842             : 
     843           0 : void Channel::RecordNotification(int32_t id, uint32_t durationMs) {
     844             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     845             :                "Channel::RecordNotification(id=%d, durationMs=%d)", id,
     846             :                durationMs);
     847             : 
     848             :   // Not implement yet
     849           0 : }
     850             : 
     851           0 : void Channel::PlayFileEnded(int32_t id) {
     852             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     853             :                "Channel::PlayFileEnded(id=%d)", id);
     854             : 
     855           0 :   if (id == _inputFilePlayerId) {
     856           0 :     channel_state_.SetInputFilePlaying(false);
     857             :     WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     858             :                  "Channel::PlayFileEnded() => input file player module is"
     859             :                  " shutdown");
     860           0 :   } else if (id == _outputFilePlayerId) {
     861           0 :     channel_state_.SetOutputFilePlaying(false);
     862             :     WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     863             :                  "Channel::PlayFileEnded() => output file player module is"
     864             :                  " shutdown");
     865             :   }
     866           0 : }
     867             : 
     868           0 : void Channel::RecordFileEnded(int32_t id) {
     869             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
     870             :                "Channel::RecordFileEnded(id=%d)", id);
     871             : 
     872           0 :   assert(id == _outputFileRecorderId);
     873             : 
     874           0 :   rtc::CritScope cs(&_fileCritSect);
     875             : 
     876           0 :   _outputFileRecording = false;
     877             :   WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId, _channelId),
     878             :                "Channel::RecordFileEnded() => output file recorder module is"
     879             :                " shutdown");
     880           0 : }
     881             : 
     882           0 : Channel::Channel(int32_t channelId,
     883             :                  uint32_t instanceId,
     884           0 :                  const VoEBase::ChannelConfig& config)
     885             :     : _instanceId(instanceId),
     886             :       _channelId(channelId),
     887           0 :       event_log_proxy_(new RtcEventLogProxy()),
     888           0 :       rtcp_rtt_stats_proxy_(new RtcpRttStatsProxy()),
     889             :       rtp_header_parser_(RtpHeaderParser::Create()),
     890           0 :       rtp_payload_registry_(new RTPPayloadRegistry()),
     891             :       rtp_receive_statistics_(
     892             :           ReceiveStatistics::Create(Clock::GetRealTimeClock())),
     893             :       rtp_receiver_(
     894             :           RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(),
     895             :                                            this,
     896             :                                            this,
     897             :                                            rtp_payload_registry_.get())),
     898           0 :       telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()),
     899             :       _outputAudioLevel(),
     900             :       _externalTransport(false),
     901             :       // Avoid conflict with other channels by adding 1024 - 1026,
     902             :       // won't use as much as 1024 channels.
     903           0 :       _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024),
     904           0 :       _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025),
     905           0 :       _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026),
     906             :       _outputFileRecording(false),
     907             :       _outputExternalMedia(false),
     908             :       _inputExternalMediaCallbackPtr(NULL),
     909             :       _outputExternalMediaCallbackPtr(NULL),
     910             :       _timeStamp(0),  // This is just an offset, RTP module will add it's own
     911             :                       // random offset
     912             :       ntp_estimator_(Clock::GetRealTimeClock()),
     913             :       playout_timestamp_rtp_(0),
     914             :       playout_timestamp_rtcp_(0),
     915             :       playout_delay_ms_(0),
     916             :       _numberOfDiscardedPackets(0),
     917             :       send_sequence_number_(0),
     918           0 :       rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()),
     919             :       capture_start_rtp_time_stamp_(-1),
     920             :       capture_start_ntp_time_ms_(-1),
     921             :       _engineStatisticsPtr(NULL),
     922             :       _outputMixerPtr(NULL),
     923             :       _transmitMixerPtr(NULL),
     924             :       _moduleProcessThreadPtr(NULL),
     925             :       _audioDeviceModulePtr(NULL),
     926             :       _voiceEngineObserverPtr(NULL),
     927             :       _callbackCritSectPtr(NULL),
     928             :       _transportPtr(NULL),
     929             :       _sendFrameType(0),
     930             :       _externalMixing(false),
     931             :       _mixFileWithMicrophone(false),
     932             :       input_mute_(false),
     933             :       previous_frame_muted_(false),
     934             :       _panLeft(1.0f),
     935             :       _panRight(1.0f),
     936             :       _outputGain(1.0f),
     937             :       _lastLocalTimeStamp(0),
     938             :       _lastPayloadType(0),
     939             :       _includeAudioLevelIndication(false),
     940             :       transport_overhead_per_packet_(0),
     941             :       rtp_overhead_per_packet_(0),
     942             :       _outputSpeechType(AudioFrame::kNormalSpeech),
     943             :       _current_sync_offset(0),
     944             :       restored_packet_in_use_(false),
     945           0 :       rtcp_observer_(new VoERtcpObserver(this)),
     946             :       associate_send_channel_(ChannelOwner(nullptr)),
     947           0 :       pacing_enabled_(config.enable_voice_pacing),
     948           0 :       feedback_observer_proxy_(new TransportFeedbackProxy()),
     949           0 :       seq_num_allocator_proxy_(new TransportSequenceNumberProxy()),
     950           0 :       rtp_packet_sender_proxy_(new RtpPacketSenderProxy()),
     951           0 :       retransmission_rate_limiter_(new RateLimiter(Clock::GetRealTimeClock(),
     952           0 :                                                    kMaxRetransmissionWindowMs)),
     953           0 :       decoder_factory_(config.acm_config.decoder_factory) {
     954             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId),
     955             :                "Channel::Channel() - ctor");
     956           0 :   AudioCodingModule::Config acm_config(config.acm_config);
     957           0 :   acm_config.id = VoEModuleId(instanceId, channelId);
     958           0 :   acm_config.neteq_config.enable_muted_state = true;
     959           0 :   audio_coding_.reset(AudioCodingModule::Create(acm_config));
     960             : 
     961           0 :   _outputAudioLevel.Clear();
     962             : 
     963           0 :   RtpRtcp::Configuration configuration;
     964           0 :   configuration.audio = true;
     965           0 :   configuration.outgoing_transport = this;
     966           0 :   configuration.overhead_observer = this;
     967           0 :   configuration.receive_statistics = rtp_receive_statistics_.get();
     968           0 :   configuration.bandwidth_callback = rtcp_observer_.get();
     969           0 :   if (pacing_enabled_) {
     970           0 :     configuration.paced_sender = rtp_packet_sender_proxy_.get();
     971           0 :     configuration.transport_sequence_number_allocator =
     972           0 :         seq_num_allocator_proxy_.get();
     973           0 :     configuration.transport_feedback_callback = feedback_observer_proxy_.get();
     974             :   }
     975           0 :   configuration.event_log = &(*event_log_proxy_);
     976           0 :   configuration.rtt_stats = &(*rtcp_rtt_stats_proxy_);
     977           0 :   configuration.retransmission_rate_limiter =
     978           0 :       retransmission_rate_limiter_.get();
     979             : 
     980           0 :   configuration.rtcp_packet_type_counter_observer = statistics_proxy_.get();
     981             :   
     982           0 :   _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
     983           0 :   _rtpRtcpModule->SetSendingMediaStatus(false);
     984             : 
     985           0 :   statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC()));
     986           0 :   rtp_receive_statistics_->RegisterRtcpStatisticsCallback(
     987           0 :       statistics_proxy_.get());
     988           0 : }
     989             : 
     990           0 : Channel::~Channel() {
     991           0 :   rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
     992             :   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId, _channelId),
     993             :                "Channel::~Channel() - dtor");
     994             : 
     995           0 :   if (_outputExternalMedia) {
     996           0 :     DeRegisterExternalMediaProcessing(kPlaybackPerChannel);
     997             :   }
     998           0 :   if (channel_state_.Get().input_external_media) {
     999           0 :     DeRegisterExternalMediaProcessing(kRecordingPerChannel);
    1000             :   }
    1001           0 :   StopSend();
    1002           0 :   StopPlayout();
    1003             : 
    1004             :   {
    1005           0 :     rtc::CritScope cs(&_fileCritSect);
    1006           0 :     if (input_file_player_) {
    1007           0 :       input_file_player_->RegisterModuleFileCallback(NULL);
    1008           0 :       input_file_player_->StopPlayingFile();
    1009             :     }
    1010           0 :     if (output_file_player_) {
    1011           0 :       output_file_player_->RegisterModuleFileCallback(NULL);
    1012           0 :       output_file_player_->StopPlayingFile();
    1013             :     }
    1014           0 :     if (output_file_recorder_) {
    1015           0 :       output_file_recorder_->RegisterModuleFileCallback(NULL);
    1016           0 :       output_file_recorder_->StopRecording();
    1017             :     }
    1018             :   }
    1019             : 
    1020             :   // The order to safely shutdown modules in a channel is:
    1021             :   // 1. De-register callbacks in modules
    1022             :   // 2. De-register modules in process thread
    1023             :   // 3. Destroy modules
    1024           0 :   if (audio_coding_->RegisterTransportCallback(NULL) == -1) {
    1025             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    1026             :                  "~Channel() failed to de-register transport callback"
    1027             :                  " (Audio coding module)");
    1028             :   }
    1029           0 :   if (audio_coding_->RegisterVADCallback(NULL) == -1) {
    1030             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    1031             :                  "~Channel() failed to de-register VAD callback"
    1032             :                  " (Audio coding module)");
    1033             :   }
    1034             :   // De-register modules in process thread
    1035           0 :   _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get());
    1036             : 
    1037             :   // End of modules shutdown
    1038           0 : }
    1039             : 
    1040           0 : int32_t Channel::Init() {
    1041             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1042             :                "Channel::Init()");
    1043             : 
    1044           0 :   channel_state_.Reset();
    1045             : 
    1046             :   // --- Initial sanity
    1047             : 
    1048           0 :   if ((_engineStatisticsPtr == NULL) || (_moduleProcessThreadPtr == NULL)) {
    1049             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
    1050             :                  "Channel::Init() must call SetEngineInformation() first");
    1051           0 :     return -1;
    1052             :   }
    1053             : 
    1054             :   // --- Add modules to process thread (for periodic schedulation)
    1055             : 
    1056           0 :   _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get());
    1057             : 
    1058             :   // --- ACM initialization
    1059             : 
    1060           0 :   if (audio_coding_->InitializeReceiver() == -1) {
    1061           0 :     _engineStatisticsPtr->SetLastError(
    1062             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1063           0 :         "Channel::Init() unable to initialize the ACM - 1");
    1064           0 :     return -1;
    1065             :   }
    1066             : 
    1067             :   // --- RTP/RTCP module initialization
    1068             : 
    1069             :   // Ensure that RTCP is enabled by default for the created channel.
    1070             :   // Note that, the module will keep generating RTCP until it is explicitly
    1071             :   // disabled by the user.
    1072             :   // After StopListen (when no sockets exists), RTCP packets will no longer
    1073             :   // be transmitted since the Transport object will then be invalid.
    1074           0 :   telephone_event_handler_->SetTelephoneEventForwardToDecoder(true);
    1075             :   // RTCP is enabled by default.
    1076           0 :   _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
    1077             :   // --- Register all permanent callbacks
    1078           0 :   const bool fail = (audio_coding_->RegisterTransportCallback(this) == -1) ||
    1079           0 :                     (audio_coding_->RegisterVADCallback(this) == -1);
    1080             : 
    1081           0 :   if (fail) {
    1082           0 :     _engineStatisticsPtr->SetLastError(
    1083             :         VE_CANNOT_INIT_CHANNEL, kTraceError,
    1084           0 :         "Channel::Init() callbacks not registered");
    1085           0 :     return -1;
    1086             :   }
    1087             : 
    1088             :   // --- Register all supported codecs to the receiving side of the
    1089             :   // RTP/RTCP module
    1090             : 
    1091             :   CodecInst codec;
    1092           0 :   const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
    1093             : 
    1094           0 :   for (int idx = 0; idx < nSupportedCodecs; idx++) {
    1095             :     // Open up the RTP/RTCP receiver for all supported codecs
    1096           0 :     if ((audio_coding_->Codec(idx, &codec) == -1) ||
    1097           0 :         (rtp_receiver_->RegisterReceivePayload(codec) == -1)) {
    1098             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    1099             :                    "Channel::Init() unable to register %s "
    1100             :                    "(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver",
    1101             :                    codec.plname, codec.pltype, codec.plfreq, codec.channels,
    1102             :                    codec.rate);
    1103             :     } else {
    1104             :       WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1105             :                    "Channel::Init() %s (%d/%d/%" PRIuS
    1106             :                    "/%d) has been "
    1107             :                    "added to the RTP/RTCP receiver",
    1108             :                    codec.plname, codec.pltype, codec.plfreq, codec.channels,
    1109             :                    codec.rate);
    1110             :     }
    1111             : 
    1112             :     // Ensure that PCMU is used as default codec on the sending side
    1113           0 :     if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1)) {
    1114           0 :       SetSendCodec(codec);
    1115             :     }
    1116             : 
    1117             :     // Register default PT for outband 'telephone-event'
    1118           0 :     if (!STR_CASE_CMP(codec.plname, "telephone-event")) {
    1119           0 :       if (_rtpRtcpModule->RegisterSendPayload(codec) == -1 ||
    1120           0 :           !audio_coding_->RegisterReceiveCodec(codec.pltype,
    1121           0 :                                                CodecInstToSdp(codec))) {
    1122             :         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    1123             :                      "Channel::Init() failed to register outband "
    1124             :                      "'telephone-event' (%d/%d) correctly",
    1125             :                      codec.pltype, codec.plfreq);
    1126             :       }
    1127             :     }
    1128             : 
    1129           0 :     if (!STR_CASE_CMP(codec.plname, "CN")) {
    1130           0 :       if (!codec_manager_.RegisterEncoder(codec) ||
    1131           0 :           !codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get()) ||
    1132           0 :           !audio_coding_->RegisterReceiveCodec(codec.pltype,
    1133           0 :                                                CodecInstToSdp(codec)) ||
    1134           0 :           _rtpRtcpModule->RegisterSendPayload(codec) == -1) {
    1135             :         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    1136             :                      "Channel::Init() failed to register CN (%d/%d) "
    1137             :                      "correctly - 1",
    1138             :                      codec.pltype, codec.plfreq);
    1139             :       }
    1140             :     }
    1141             :   }
    1142             : 
    1143           0 :   return 0;
    1144             : }
    1145             : 
    1146           0 : int32_t Channel::SetEngineInformation(Statistics& engineStatistics,
    1147             :                                       OutputMixer& outputMixer,
    1148             :                                       voe::TransmitMixer& transmitMixer,
    1149             :                                       ProcessThread& moduleProcessThread,
    1150             :                                       AudioDeviceModule& audioDeviceModule,
    1151             :                                       VoiceEngineObserver* voiceEngineObserver,
    1152             :                                       rtc::CriticalSection* callbackCritSect) {
    1153             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1154             :                "Channel::SetEngineInformation()");
    1155           0 :   _engineStatisticsPtr = &engineStatistics;
    1156           0 :   _outputMixerPtr = &outputMixer;
    1157           0 :   _transmitMixerPtr = &transmitMixer;
    1158           0 :   _moduleProcessThreadPtr = &moduleProcessThread;
    1159           0 :   _audioDeviceModulePtr = &audioDeviceModule;
    1160           0 :   _voiceEngineObserverPtr = voiceEngineObserver;
    1161           0 :   _callbackCritSectPtr = callbackCritSect;
    1162           0 :   return 0;
    1163             : }
    1164             : 
    1165           0 : int32_t Channel::UpdateLocalTimeStamp() {
    1166           0 :   _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_);
    1167           0 :   return 0;
    1168             : }
    1169             : 
    1170           0 : void Channel::SetSink(std::unique_ptr<AudioSinkInterface> sink) {
    1171           0 :   rtc::CritScope cs(&_callbackCritSect);
    1172           0 :   audio_sink_ = std::move(sink);
    1173           0 : }
    1174             : 
    1175             : const rtc::scoped_refptr<AudioDecoderFactory>&
    1176           0 : Channel::GetAudioDecoderFactory() const {
    1177           0 :   return decoder_factory_;
    1178             : }
    1179             : 
    1180           0 : int32_t Channel::StartPlayout() {
    1181             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1182             :                "Channel::StartPlayout()");
    1183           0 :   if (channel_state_.Get().playing) {
    1184           0 :     return 0;
    1185             :   }
    1186             : 
    1187           0 :   if (!_externalMixing) {
    1188             :     // Add participant as candidates for mixing.
    1189           0 :     if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0) {
    1190           0 :       _engineStatisticsPtr->SetLastError(
    1191             :           VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
    1192           0 :           "StartPlayout() failed to add participant to mixer");
    1193           0 :       return -1;
    1194             :     }
    1195             :   }
    1196             : 
    1197           0 :   channel_state_.SetPlaying(true);
    1198           0 :   if (RegisterFilePlayingToMixer() != 0)
    1199           0 :     return -1;
    1200             : 
    1201           0 :   return 0;
    1202             : }
    1203             : 
    1204           0 : int32_t Channel::StopPlayout() {
    1205             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1206             :                "Channel::StopPlayout()");
    1207           0 :   if (!channel_state_.Get().playing) {
    1208           0 :     return 0;
    1209             :   }
    1210             : 
    1211           0 :   if (!_externalMixing) {
    1212             :     // Remove participant as candidates for mixing
    1213           0 :     if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0) {
    1214           0 :       _engineStatisticsPtr->SetLastError(
    1215             :           VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
    1216           0 :           "StopPlayout() failed to remove participant from mixer");
    1217           0 :       return -1;
    1218             :     }
    1219             :   }
    1220             : 
    1221           0 :   channel_state_.SetPlaying(false);
    1222           0 :   _outputAudioLevel.Clear();
    1223             : 
    1224           0 :   return 0;
    1225             : }
    1226             : 
    1227           0 : int32_t Channel::StartSend() {
    1228             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1229             :                "Channel::StartSend()");
    1230             :   // Resume the previous sequence number which was reset by StopSend().
    1231             :   // This needs to be done before |sending| is set to true.
    1232           0 :   if (send_sequence_number_)
    1233           0 :     SetInitSequenceNumber(send_sequence_number_);
    1234             : 
    1235           0 :   if (channel_state_.Get().sending) {
    1236           0 :     return 0;
    1237             :   }
    1238           0 :   channel_state_.SetSending(true);
    1239             : 
    1240           0 :   _rtpRtcpModule->SetSendingMediaStatus(true);
    1241           0 :   if (_rtpRtcpModule->SetSendingStatus(true) != 0) {
    1242           0 :     _engineStatisticsPtr->SetLastError(
    1243             :         VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    1244           0 :         "StartSend() RTP/RTCP failed to start sending");
    1245           0 :     _rtpRtcpModule->SetSendingMediaStatus(false);
    1246           0 :     rtc::CritScope cs(&_callbackCritSect);
    1247           0 :     channel_state_.SetSending(false);
    1248           0 :     return -1;
    1249             :   }
    1250             : 
    1251           0 :   return 0;
    1252             : }
    1253             : 
    1254           0 : int32_t Channel::StopSend() {
    1255             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1256             :                "Channel::StopSend()");
    1257           0 :   if (!channel_state_.Get().sending) {
    1258           0 :     return 0;
    1259             :   }
    1260           0 :   channel_state_.SetSending(false);
    1261             : 
    1262             :   // Store the sequence number to be able to pick up the same sequence for
    1263             :   // the next StartSend(). This is needed for restarting device, otherwise
    1264             :   // it might cause libSRTP to complain about packets being replayed.
    1265             :   // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring
    1266             :   // CL is landed. See issue
    1267             :   // https://code.google.com/p/webrtc/issues/detail?id=2111 .
    1268           0 :   send_sequence_number_ = _rtpRtcpModule->SequenceNumber();
    1269             : 
    1270             :   // Reset sending SSRC and sequence number and triggers direct transmission
    1271             :   // of RTCP BYE
    1272           0 :   if (_rtpRtcpModule->SetSendingStatus(false) == -1) {
    1273           0 :     _engineStatisticsPtr->SetLastError(
    1274             :         VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
    1275           0 :         "StartSend() RTP/RTCP failed to stop sending");
    1276             :   }
    1277           0 :   _rtpRtcpModule->SetSendingMediaStatus(false);
    1278             : 
    1279           0 :   return 0;
    1280             : }
    1281             : 
    1282           0 : void Channel::ResetDiscardedPacketCount() {
    1283             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1284             :                "Channel::ResetDiscardedPacketCount()");
    1285           0 :   _numberOfDiscardedPackets = 0;
    1286           0 : }
    1287             : 
    1288           0 : int32_t Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer) {
    1289             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1290             :                "Channel::RegisterVoiceEngineObserver()");
    1291           0 :   rtc::CritScope cs(&_callbackCritSect);
    1292             : 
    1293           0 :   if (_voiceEngineObserverPtr) {
    1294           0 :     _engineStatisticsPtr->SetLastError(
    1295             :         VE_INVALID_OPERATION, kTraceError,
    1296           0 :         "RegisterVoiceEngineObserver() observer already enabled");
    1297           0 :     return -1;
    1298             :   }
    1299           0 :   _voiceEngineObserverPtr = &observer;
    1300           0 :   return 0;
    1301             : }
    1302             : 
    1303           0 : int32_t Channel::DeRegisterVoiceEngineObserver() {
    1304             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1305             :                "Channel::DeRegisterVoiceEngineObserver()");
    1306           0 :   rtc::CritScope cs(&_callbackCritSect);
    1307             : 
    1308           0 :   if (!_voiceEngineObserverPtr) {
    1309           0 :     _engineStatisticsPtr->SetLastError(
    1310             :         VE_INVALID_OPERATION, kTraceWarning,
    1311           0 :         "DeRegisterVoiceEngineObserver() observer already disabled");
    1312           0 :     return 0;
    1313             :   }
    1314           0 :   _voiceEngineObserverPtr = NULL;
    1315           0 :   return 0;
    1316             : }
    1317             : 
    1318           0 : int32_t Channel::GetSendCodec(CodecInst& codec) {
    1319           0 :   auto send_codec = codec_manager_.GetCodecInst();
    1320           0 :   if (send_codec) {
    1321           0 :     codec = *send_codec;
    1322           0 :     return 0;
    1323             :   }
    1324           0 :   return -1;
    1325             : }
    1326             : 
    1327           0 : int32_t Channel::GetRecCodec(CodecInst& codec) {
    1328           0 :   return (audio_coding_->ReceiveCodec(&codec));
    1329             : }
    1330             : 
    1331           0 : int32_t Channel::SetSendCodec(const CodecInst& codec) {
    1332             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1333             :                "Channel::SetSendCodec()");
    1334             : 
    1335           0 :   if (!codec_manager_.RegisterEncoder(codec) ||
    1336           0 :       !codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get())) {
    1337             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
    1338             :                  "SetSendCodec() failed to register codec to ACM");
    1339           0 :     return -1;
    1340             :   }
    1341             : 
    1342           0 :   if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    1343           0 :     _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
    1344           0 :     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    1345             :       WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
    1346             :                    "SetSendCodec() failed to register codec to"
    1347             :                    " RTP/RTCP module");
    1348           0 :       return -1;
    1349             :     }
    1350             :   }
    1351             : 
    1352           0 :   return 0;
    1353             : }
    1354             : 
    1355           0 : void Channel::SetBitRate(int bitrate_bps, int64_t probing_interval_ms) {
    1356             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1357             :                "Channel::SetBitRate(bitrate_bps=%d)", bitrate_bps);
    1358           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1359           0 :     if (*encoder) {
    1360           0 :       (*encoder)->OnReceivedUplinkBandwidth(
    1361           0 :           bitrate_bps, rtc::Optional<int64_t>(probing_interval_ms));
    1362             :     }
    1363           0 :   });
    1364           0 :   retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
    1365           0 : }
    1366             : 
    1367           0 : void Channel::OnIncomingFractionLoss(int fraction_lost) {
    1368           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1369           0 :     if (*encoder)
    1370           0 :       (*encoder)->OnReceivedUplinkPacketLossFraction(fraction_lost / 255.0f);
    1371           0 :   });
    1372           0 : }
    1373             : 
    1374           0 : int32_t Channel::SetVADStatus(bool enableVAD,
    1375             :                               ACMVADMode mode,
    1376             :                               bool disableDTX) {
    1377             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1378             :                "Channel::SetVADStatus(mode=%d)", mode);
    1379           0 :   RTC_DCHECK(!(disableDTX && enableVAD));  // disableDTX mode is deprecated.
    1380           0 :   if (!codec_manager_.SetVAD(enableVAD, mode) ||
    1381           0 :       !codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get())) {
    1382           0 :     _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR,
    1383             :                                        kTraceError,
    1384           0 :                                        "SetVADStatus() failed to set VAD");
    1385           0 :     return -1;
    1386             :   }
    1387           0 :   return 0;
    1388             : }
    1389             : 
    1390           0 : int32_t Channel::GetVADStatus(bool& enabledVAD,
    1391             :                               ACMVADMode& mode,
    1392             :                               bool& disabledDTX) {
    1393           0 :   const auto* params = codec_manager_.GetStackParams();
    1394           0 :   enabledVAD = params->use_cng;
    1395           0 :   mode = params->vad_mode;
    1396           0 :   disabledDTX = !params->use_cng;
    1397           0 :   return 0;
    1398             : }
    1399             : 
    1400           0 : int32_t Channel::SetRecPayloadType(const CodecInst& codec) {
    1401             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1402             :                "Channel::SetRecPayloadType()");
    1403             : 
    1404           0 :   if (channel_state_.Get().playing) {
    1405           0 :     _engineStatisticsPtr->SetLastError(
    1406             :         VE_ALREADY_PLAYING, kTraceError,
    1407           0 :         "SetRecPayloadType() unable to set PT while playing");
    1408           0 :     return -1;
    1409             :   }
    1410             : 
    1411           0 :   if (codec.pltype == -1) {
    1412             :     // De-register the selected codec (RTP/RTCP module and ACM)
    1413             : 
    1414           0 :     int8_t pltype(-1);
    1415           0 :     CodecInst rxCodec = codec;
    1416             : 
    1417             :     // Get payload type for the given codec
    1418           0 :     rtp_payload_registry_->ReceivePayloadType(rxCodec, &pltype);
    1419           0 :     rxCodec.pltype = pltype;
    1420             : 
    1421           0 :     if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0) {
    1422           0 :       _engineStatisticsPtr->SetLastError(
    1423             :           VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    1424             :           "SetRecPayloadType() RTP/RTCP-module deregistration "
    1425           0 :           "failed");
    1426           0 :       return -1;
    1427             :     }
    1428           0 :     if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0) {
    1429           0 :       _engineStatisticsPtr->SetLastError(
    1430             :           VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1431           0 :           "SetRecPayloadType() ACM deregistration failed - 1");
    1432           0 :       return -1;
    1433             :     }
    1434           0 :     return 0;
    1435             :   }
    1436             : 
    1437           0 :   if (rtp_receiver_->RegisterReceivePayload(codec) != 0) {
    1438             :     // First attempt to register failed => de-register and try again
    1439             :     // TODO(kwiberg): Retrying is probably not necessary, since
    1440             :     // AcmReceiver::AddCodec also retries.
    1441           0 :     rtp_receiver_->DeRegisterReceivePayload(codec.pltype);
    1442           0 :     if (rtp_receiver_->RegisterReceivePayload(codec) != 0) {
    1443           0 :       _engineStatisticsPtr->SetLastError(
    1444             :           VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    1445           0 :           "SetRecPayloadType() RTP/RTCP-module registration failed");
    1446           0 :       return -1;
    1447             :     }
    1448             :   }
    1449           0 :   if (!audio_coding_->RegisterReceiveCodec(codec.pltype,
    1450           0 :                                            CodecInstToSdp(codec))) {
    1451           0 :     audio_coding_->UnregisterReceiveCodec(codec.pltype);
    1452           0 :     if (!audio_coding_->RegisterReceiveCodec(codec.pltype,
    1453           0 :                                              CodecInstToSdp(codec))) {
    1454           0 :       _engineStatisticsPtr->SetLastError(
    1455             :           VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1456           0 :           "SetRecPayloadType() ACM registration failed - 1");
    1457           0 :       return -1;
    1458             :     }
    1459             :   }
    1460           0 :   return 0;
    1461             : }
    1462             : 
    1463           0 : int32_t Channel::GetRecPayloadType(CodecInst& codec) {
    1464           0 :   int8_t payloadType(-1);
    1465           0 :   if (rtp_payload_registry_->ReceivePayloadType(codec, &payloadType) != 0) {
    1466           0 :     _engineStatisticsPtr->SetLastError(
    1467             :         VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
    1468           0 :         "GetRecPayloadType() failed to retrieve RX payload type");
    1469           0 :     return -1;
    1470             :   }
    1471           0 :   codec.pltype = payloadType;
    1472           0 :   return 0;
    1473             : }
    1474             : 
    1475           0 : int32_t Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency) {
    1476             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1477             :                "Channel::SetSendCNPayloadType()");
    1478             : 
    1479             :   CodecInst codec;
    1480           0 :   int32_t samplingFreqHz(-1);
    1481           0 :   const size_t kMono = 1;
    1482           0 :   if (frequency == kFreq32000Hz)
    1483           0 :     samplingFreqHz = 32000;
    1484           0 :   else if (frequency == kFreq16000Hz)
    1485           0 :     samplingFreqHz = 16000;
    1486             : 
    1487           0 :   if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1) {
    1488           0 :     _engineStatisticsPtr->SetLastError(
    1489             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1490             :         "SetSendCNPayloadType() failed to retrieve default CN codec "
    1491           0 :         "settings");
    1492           0 :     return -1;
    1493             :   }
    1494             : 
    1495             :   // Modify the payload type (must be set to dynamic range)
    1496           0 :   codec.pltype = type;
    1497             : 
    1498           0 :   if (!codec_manager_.RegisterEncoder(codec) ||
    1499           0 :       !codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get())) {
    1500           0 :     _engineStatisticsPtr->SetLastError(
    1501             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1502           0 :         "SetSendCNPayloadType() failed to register CN to ACM");
    1503           0 :     return -1;
    1504             :   }
    1505             : 
    1506           0 :   if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    1507           0 :     _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
    1508           0 :     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    1509           0 :       _engineStatisticsPtr->SetLastError(
    1510             :           VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    1511             :           "SetSendCNPayloadType() failed to register CN to RTP/RTCP "
    1512           0 :           "module");
    1513           0 :       return -1;
    1514             :     }
    1515             :   }
    1516           0 :   return 0;
    1517             : }
    1518             : 
    1519           0 : int Channel::SetOpusMaxPlaybackRate(int frequency_hz) {
    1520             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1521             :                "Channel::SetOpusMaxPlaybackRate()");
    1522             : 
    1523           0 :   if (audio_coding_->SetOpusMaxPlaybackRate(frequency_hz) != 0) {
    1524           0 :     _engineStatisticsPtr->SetLastError(
    1525             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    1526           0 :         "SetOpusMaxPlaybackRate() failed to set maximum playback rate");
    1527           0 :     return -1;
    1528             :   }
    1529           0 :   return 0;
    1530             : }
    1531             : 
    1532           0 : int Channel::SetOpusDtx(bool enable_dtx) {
    1533             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1534             :                "Channel::SetOpusDtx(%d)", enable_dtx);
    1535           0 :   int ret = enable_dtx ? audio_coding_->EnableOpusDtx()
    1536           0 :                        : audio_coding_->DisableOpusDtx();
    1537           0 :   if (ret != 0) {
    1538           0 :     _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR,
    1539           0 :                                        kTraceError, "SetOpusDtx() failed");
    1540           0 :     return -1;
    1541             :   }
    1542           0 :   return 0;
    1543             : }
    1544             : 
    1545           0 : int Channel::GetOpusDtx(bool* enabled) {
    1546           0 :   int success = -1;
    1547           0 :   audio_coding_->QueryEncoder([&](AudioEncoder const* encoder) {
    1548           0 :     if (encoder) {
    1549           0 :       *enabled = encoder->GetDtx();
    1550           0 :       success = 0;
    1551             :     }
    1552           0 :   });
    1553           0 :   return success;
    1554             : }
    1555             : 
    1556           0 : bool Channel::EnableAudioNetworkAdaptor(const std::string& config_string) {
    1557           0 :   bool success = false;
    1558           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1559           0 :     if (*encoder) {
    1560           0 :       success = (*encoder)->EnableAudioNetworkAdaptor(
    1561           0 :           config_string, event_log_proxy_.get(), Clock::GetRealTimeClock());
    1562             :     }
    1563           0 :   });
    1564           0 :   return success;
    1565             : }
    1566             : 
    1567           0 : void Channel::DisableAudioNetworkAdaptor() {
    1568           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1569           0 :     if (*encoder)
    1570           0 :       (*encoder)->DisableAudioNetworkAdaptor();
    1571           0 :   });
    1572           0 : }
    1573             : 
    1574           0 : void Channel::SetReceiverFrameLengthRange(int min_frame_length_ms,
    1575             :                                           int max_frame_length_ms) {
    1576           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1577           0 :     if (*encoder) {
    1578           0 :       (*encoder)->SetReceiverFrameLengthRange(min_frame_length_ms,
    1579           0 :                                               max_frame_length_ms);
    1580             :     }
    1581           0 :   });
    1582           0 : }
    1583             : 
    1584           0 : int32_t Channel::RegisterExternalTransport(Transport* transport) {
    1585             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1586             :                "Channel::RegisterExternalTransport()");
    1587             : 
    1588           0 :   rtc::CritScope cs(&_callbackCritSect);
    1589           0 :   if (_externalTransport) {
    1590           0 :     _engineStatisticsPtr->SetLastError(
    1591             :         VE_INVALID_OPERATION, kTraceError,
    1592           0 :         "RegisterExternalTransport() external transport already enabled");
    1593           0 :     return -1;
    1594             :   }
    1595           0 :   _externalTransport = true;
    1596           0 :   _transportPtr = transport;
    1597           0 :   return 0;
    1598             : }
    1599             : 
    1600           0 : int32_t Channel::DeRegisterExternalTransport() {
    1601             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1602             :                "Channel::DeRegisterExternalTransport()");
    1603             : 
    1604           0 :   rtc::CritScope cs(&_callbackCritSect);
    1605           0 :   if (_transportPtr) {
    1606             :     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1607             :                  "DeRegisterExternalTransport() all transport is disabled");
    1608             :   } else {
    1609           0 :     _engineStatisticsPtr->SetLastError(
    1610             :         VE_INVALID_OPERATION, kTraceWarning,
    1611             :         "DeRegisterExternalTransport() external transport already "
    1612           0 :         "disabled");
    1613             :   }
    1614           0 :   _externalTransport = false;
    1615           0 :   _transportPtr = NULL;
    1616           0 :   return 0;
    1617             : }
    1618             : 
    1619           0 : int32_t Channel::ReceivedRTPPacket(const uint8_t* received_packet,
    1620             :                                    size_t length,
    1621             :                                    const PacketTime& packet_time) {
    1622             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    1623             :                "Channel::ReceivedRTPPacket()");
    1624             : 
    1625             :   // Store playout timestamp for the received RTP packet
    1626           0 :   UpdatePlayoutTimestamp(false);
    1627             : 
    1628           0 :   RTPHeader header;
    1629           0 :   if (!rtp_header_parser_->Parse(received_packet, length, &header)) {
    1630             :     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
    1631             :                  "Incoming packet: invalid RTP header");
    1632           0 :     return -1;
    1633             :   }
    1634           0 :   header.payload_type_frequency =
    1635           0 :       rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
    1636           0 :   if (header.payload_type_frequency < 0)
    1637           0 :     return -1;
    1638           0 :   bool in_order = IsPacketInOrder(header);
    1639           0 :   rtp_receive_statistics_->IncomingPacket(
    1640           0 :       header, length, IsPacketRetransmitted(header, in_order));
    1641           0 :   rtp_payload_registry_->SetIncomingPayloadType(header);
    1642             : 
    1643           0 :   return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1;
    1644             : }
    1645             : 
    1646           0 : bool Channel::ReceivePacket(const uint8_t* packet,
    1647             :                             size_t packet_length,
    1648             :                             const RTPHeader& header,
    1649             :                             bool in_order) {
    1650           0 :   if (rtp_payload_registry_->IsRtx(header)) {
    1651           0 :     return HandleRtxPacket(packet, packet_length, header);
    1652             :   }
    1653           0 :   const uint8_t* payload = packet + header.headerLength;
    1654           0 :   assert(packet_length >= header.headerLength);
    1655           0 :   size_t payload_length = packet_length - header.headerLength;
    1656             :   PayloadUnion payload_specific;
    1657           0 :   if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
    1658             :                                                   &payload_specific)) {
    1659           0 :     return false;
    1660             :   }
    1661           0 :   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
    1662           0 :                                           payload_specific, in_order);
    1663             : }
    1664             : 
    1665           0 : bool Channel::HandleRtxPacket(const uint8_t* packet,
    1666             :                               size_t packet_length,
    1667             :                               const RTPHeader& header) {
    1668           0 :   if (!rtp_payload_registry_->IsRtx(header))
    1669           0 :     return false;
    1670             : 
    1671             :   // Remove the RTX header and parse the original RTP header.
    1672           0 :   if (packet_length < header.headerLength)
    1673           0 :     return false;
    1674           0 :   if (packet_length > kVoiceEngineMaxIpPacketSizeBytes)
    1675           0 :     return false;
    1676           0 :   if (restored_packet_in_use_) {
    1677             :     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
    1678             :                  "Multiple RTX headers detected, dropping packet");
    1679           0 :     return false;
    1680             :   }
    1681           0 :   if (!rtp_payload_registry_->RestoreOriginalPacket(
    1682           0 :           restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(),
    1683             :           header)) {
    1684             :     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
    1685             :                  "Incoming RTX packet: invalid RTP header");
    1686           0 :     return false;
    1687             :   }
    1688           0 :   restored_packet_in_use_ = true;
    1689           0 :   bool ret = OnRecoveredPacket(restored_packet_, packet_length);
    1690           0 :   restored_packet_in_use_ = false;
    1691           0 :   return ret;
    1692             : }
    1693             : 
    1694           0 : bool Channel::IsPacketInOrder(const RTPHeader& header) const {
    1695             :   StreamStatistician* statistician =
    1696           0 :       rtp_receive_statistics_->GetStatistician(header.ssrc);
    1697           0 :   if (!statistician)
    1698           0 :     return false;
    1699           0 :   return statistician->IsPacketInOrder(header.sequenceNumber);
    1700             : }
    1701             : 
    1702           0 : bool Channel::IsPacketRetransmitted(const RTPHeader& header,
    1703             :                                     bool in_order) const {
    1704             :   // Retransmissions are handled separately if RTX is enabled.
    1705           0 :   if (rtp_payload_registry_->RtxEnabled())
    1706           0 :     return false;
    1707             :   StreamStatistician* statistician =
    1708           0 :       rtp_receive_statistics_->GetStatistician(header.ssrc);
    1709           0 :   if (!statistician)
    1710           0 :     return false;
    1711             :   // Check if this is a retransmission.
    1712           0 :   int64_t min_rtt = 0;
    1713           0 :   _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
    1714           0 :   return !in_order && statistician->IsRetransmitOfOldPacket(header, min_rtt);
    1715             : }
    1716             : 
    1717           0 : int32_t Channel::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
    1718             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    1719             :                "Channel::ReceivedRTCPPacket()");
    1720             :   // Store playout timestamp for the received RTCP packet
    1721           0 :   UpdatePlayoutTimestamp(true);
    1722             : 
    1723             :   // Deliver RTCP packet to RTP/RTCP module for parsing
    1724           0 :   if (_rtpRtcpModule->IncomingRtcpPacket(data, length) == -1) {
    1725           0 :     _engineStatisticsPtr->SetLastError(
    1726             :         VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
    1727           0 :         "Channel::IncomingRTPPacket() RTCP packet is invalid");
    1728             :   }
    1729             : 
    1730           0 :   int64_t rtt = GetRTT(true);
    1731           0 :   if (rtt == 0) {
    1732             :     // Waiting for valid RTT.
    1733           0 :     return 0;
    1734             :   }
    1735             : 
    1736           0 :   int64_t nack_window_ms = rtt;
    1737           0 :   if (nack_window_ms < kMinRetransmissionWindowMs) {
    1738           0 :     nack_window_ms = kMinRetransmissionWindowMs;
    1739           0 :   } else if (nack_window_ms > kMaxRetransmissionWindowMs) {
    1740           0 :     nack_window_ms = kMaxRetransmissionWindowMs;
    1741             :   }
    1742           0 :   retransmission_rate_limiter_->SetWindowSize(nack_window_ms);
    1743             : 
    1744             :   // Invoke audio encoders OnReceivedRtt().
    1745           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    1746           0 :     if (*encoder)
    1747           0 :       (*encoder)->OnReceivedRtt(rtt);
    1748           0 :   });
    1749             : 
    1750           0 :   uint32_t ntp_secs = 0;
    1751           0 :   uint32_t ntp_frac = 0;
    1752           0 :   uint32_t rtp_timestamp = 0;
    1753           0 :   if (0 !=
    1754           0 :       _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL,
    1755           0 :                                 &rtp_timestamp)) {
    1756             :     // Waiting for RTCP.
    1757           0 :     return 0;
    1758             :   }
    1759             : 
    1760             :   {
    1761           0 :     rtc::CritScope lock(&ts_stats_lock_);
    1762           0 :     ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp);
    1763             :   }
    1764           0 :   return 0;
    1765             : }
    1766             : 
    1767           0 : int Channel::StartPlayingFileLocally(const char* fileName,
    1768             :                                      bool loop,
    1769             :                                      FileFormats format,
    1770             :                                      int startPosition,
    1771             :                                      float volumeScaling,
    1772             :                                      int stopPosition,
    1773             :                                      const CodecInst* codecInst) {
    1774             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1775             :                "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d,"
    1776             :                " format=%d, volumeScaling=%5.3f, startPosition=%d, "
    1777             :                "stopPosition=%d)",
    1778             :                fileName, loop, format, volumeScaling, startPosition,
    1779             :                stopPosition);
    1780             : 
    1781           0 :   if (channel_state_.Get().output_file_playing) {
    1782           0 :     _engineStatisticsPtr->SetLastError(
    1783             :         VE_ALREADY_PLAYING, kTraceError,
    1784           0 :         "StartPlayingFileLocally() is already playing");
    1785           0 :     return -1;
    1786             :   }
    1787             : 
    1788             :   {
    1789           0 :     rtc::CritScope cs(&_fileCritSect);
    1790             : 
    1791           0 :     if (output_file_player_) {
    1792           0 :       output_file_player_->RegisterModuleFileCallback(NULL);
    1793           0 :       output_file_player_.reset();
    1794             :     }
    1795             : 
    1796           0 :     output_file_player_ = FilePlayer::CreateFilePlayer(
    1797           0 :         _outputFilePlayerId, (const FileFormats)format);
    1798             : 
    1799           0 :     if (!output_file_player_) {
    1800           0 :       _engineStatisticsPtr->SetLastError(
    1801             :           VE_INVALID_ARGUMENT, kTraceError,
    1802           0 :           "StartPlayingFileLocally() filePlayer format is not correct");
    1803           0 :       return -1;
    1804             :     }
    1805             : 
    1806           0 :     const uint32_t notificationTime(0);
    1807             : 
    1808           0 :     if (output_file_player_->StartPlayingFile(
    1809             :             fileName, loop, startPosition, volumeScaling, notificationTime,
    1810           0 :             stopPosition, (const CodecInst*)codecInst) != 0) {
    1811           0 :       _engineStatisticsPtr->SetLastError(
    1812             :           VE_BAD_FILE, kTraceError,
    1813           0 :           "StartPlayingFile() failed to start file playout");
    1814           0 :       output_file_player_->StopPlayingFile();
    1815           0 :       output_file_player_.reset();
    1816           0 :       return -1;
    1817             :     }
    1818           0 :     output_file_player_->RegisterModuleFileCallback(this);
    1819           0 :     channel_state_.SetOutputFilePlaying(true);
    1820             :   }
    1821             : 
    1822           0 :   if (RegisterFilePlayingToMixer() != 0)
    1823           0 :     return -1;
    1824             : 
    1825           0 :   return 0;
    1826             : }
    1827             : 
    1828           0 : int Channel::StartPlayingFileLocally(InStream* stream,
    1829             :                                      FileFormats format,
    1830             :                                      int startPosition,
    1831             :                                      float volumeScaling,
    1832             :                                      int stopPosition,
    1833             :                                      const CodecInst* codecInst) {
    1834             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1835             :                "Channel::StartPlayingFileLocally(format=%d,"
    1836             :                " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)",
    1837             :                format, volumeScaling, startPosition, stopPosition);
    1838             : 
    1839           0 :   if (stream == NULL) {
    1840           0 :     _engineStatisticsPtr->SetLastError(
    1841             :         VE_BAD_FILE, kTraceError,
    1842           0 :         "StartPlayingFileLocally() NULL as input stream");
    1843           0 :     return -1;
    1844             :   }
    1845             : 
    1846           0 :   if (channel_state_.Get().output_file_playing) {
    1847           0 :     _engineStatisticsPtr->SetLastError(
    1848             :         VE_ALREADY_PLAYING, kTraceError,
    1849           0 :         "StartPlayingFileLocally() is already playing");
    1850           0 :     return -1;
    1851             :   }
    1852             : 
    1853             :   {
    1854           0 :     rtc::CritScope cs(&_fileCritSect);
    1855             : 
    1856             :     // Destroy the old instance
    1857           0 :     if (output_file_player_) {
    1858           0 :       output_file_player_->RegisterModuleFileCallback(NULL);
    1859           0 :       output_file_player_.reset();
    1860             :     }
    1861             : 
    1862             :     // Create the instance
    1863           0 :     output_file_player_ = FilePlayer::CreateFilePlayer(
    1864           0 :         _outputFilePlayerId, (const FileFormats)format);
    1865             : 
    1866           0 :     if (!output_file_player_) {
    1867           0 :       _engineStatisticsPtr->SetLastError(
    1868             :           VE_INVALID_ARGUMENT, kTraceError,
    1869           0 :           "StartPlayingFileLocally() filePlayer format isnot correct");
    1870           0 :       return -1;
    1871             :     }
    1872             : 
    1873           0 :     const uint32_t notificationTime(0);
    1874             : 
    1875           0 :     if (output_file_player_->StartPlayingFile(stream, startPosition,
    1876             :                                               volumeScaling, notificationTime,
    1877           0 :                                               stopPosition, codecInst) != 0) {
    1878           0 :       _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
    1879             :                                          "StartPlayingFile() failed to "
    1880           0 :                                          "start file playout");
    1881           0 :       output_file_player_->StopPlayingFile();
    1882           0 :       output_file_player_.reset();
    1883           0 :       return -1;
    1884             :     }
    1885           0 :     output_file_player_->RegisterModuleFileCallback(this);
    1886           0 :     channel_state_.SetOutputFilePlaying(true);
    1887             :   }
    1888             : 
    1889           0 :   if (RegisterFilePlayingToMixer() != 0)
    1890           0 :     return -1;
    1891             : 
    1892           0 :   return 0;
    1893             : }
    1894             : 
    1895           0 : int Channel::StopPlayingFileLocally() {
    1896             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1897             :                "Channel::StopPlayingFileLocally()");
    1898             : 
    1899           0 :   if (!channel_state_.Get().output_file_playing) {
    1900           0 :     return 0;
    1901             :   }
    1902             : 
    1903             :   {
    1904           0 :     rtc::CritScope cs(&_fileCritSect);
    1905             : 
    1906           0 :     if (output_file_player_->StopPlayingFile() != 0) {
    1907           0 :       _engineStatisticsPtr->SetLastError(
    1908             :           VE_STOP_RECORDING_FAILED, kTraceError,
    1909           0 :           "StopPlayingFile() could not stop playing");
    1910           0 :       return -1;
    1911             :     }
    1912           0 :     output_file_player_->RegisterModuleFileCallback(NULL);
    1913           0 :     output_file_player_.reset();
    1914           0 :     channel_state_.SetOutputFilePlaying(false);
    1915             :   }
    1916             :   // _fileCritSect cannot be taken while calling
    1917             :   // SetAnonymousMixibilityStatus. Refer to comments in
    1918             :   // StartPlayingFileLocally(const char* ...) for more details.
    1919           0 :   if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0) {
    1920           0 :     _engineStatisticsPtr->SetLastError(
    1921             :         VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
    1922             :         "StopPlayingFile() failed to stop participant from playing as"
    1923           0 :         "file in the mixer");
    1924           0 :     return -1;
    1925             :   }
    1926             : 
    1927           0 :   return 0;
    1928             : }
    1929             : 
    1930           0 : int Channel::IsPlayingFileLocally() const {
    1931           0 :   return channel_state_.Get().output_file_playing;
    1932             : }
    1933             : 
    1934           0 : int Channel::RegisterFilePlayingToMixer() {
    1935             :   // Return success for not registering for file playing to mixer if:
    1936             :   // 1. playing file before playout is started on that channel.
    1937             :   // 2. starting playout without file playing on that channel.
    1938           0 :   if (!channel_state_.Get().playing ||
    1939           0 :       !channel_state_.Get().output_file_playing) {
    1940           0 :     return 0;
    1941             :   }
    1942             : 
    1943             :   // |_fileCritSect| cannot be taken while calling
    1944             :   // SetAnonymousMixabilityStatus() since as soon as the participant is added
    1945             :   // frames can be pulled by the mixer. Since the frames are generated from
    1946             :   // the file, _fileCritSect will be taken. This would result in a deadlock.
    1947           0 :   if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0) {
    1948           0 :     channel_state_.SetOutputFilePlaying(false);
    1949           0 :     rtc::CritScope cs(&_fileCritSect);
    1950           0 :     _engineStatisticsPtr->SetLastError(
    1951             :         VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
    1952           0 :         "StartPlayingFile() failed to add participant as file to mixer");
    1953           0 :     output_file_player_->StopPlayingFile();
    1954           0 :     output_file_player_.reset();
    1955           0 :     return -1;
    1956             :   }
    1957             : 
    1958           0 :   return 0;
    1959             : }
    1960             : 
    1961           0 : int Channel::StartPlayingFileAsMicrophone(const char* fileName,
    1962             :                                           bool loop,
    1963             :                                           FileFormats format,
    1964             :                                           int startPosition,
    1965             :                                           float volumeScaling,
    1966             :                                           int stopPosition,
    1967             :                                           const CodecInst* codecInst) {
    1968             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    1969             :                "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, "
    1970             :                "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, "
    1971             :                "stopPosition=%d)",
    1972             :                fileName, loop, format, volumeScaling, startPosition,
    1973             :                stopPosition);
    1974             : 
    1975           0 :   rtc::CritScope cs(&_fileCritSect);
    1976             : 
    1977           0 :   if (channel_state_.Get().input_file_playing) {
    1978           0 :     _engineStatisticsPtr->SetLastError(
    1979             :         VE_ALREADY_PLAYING, kTraceWarning,
    1980           0 :         "StartPlayingFileAsMicrophone() filePlayer is playing");
    1981           0 :     return 0;
    1982             :   }
    1983             : 
    1984             :   // Destroy the old instance
    1985           0 :   if (input_file_player_) {
    1986           0 :     input_file_player_->RegisterModuleFileCallback(NULL);
    1987           0 :     input_file_player_.reset();
    1988             :   }
    1989             : 
    1990             :   // Create the instance
    1991           0 :   input_file_player_ = FilePlayer::CreateFilePlayer(_inputFilePlayerId,
    1992           0 :                                                     (const FileFormats)format);
    1993             : 
    1994           0 :   if (!input_file_player_) {
    1995           0 :     _engineStatisticsPtr->SetLastError(
    1996             :         VE_INVALID_ARGUMENT, kTraceError,
    1997           0 :         "StartPlayingFileAsMicrophone() filePlayer format isnot correct");
    1998           0 :     return -1;
    1999             :   }
    2000             : 
    2001           0 :   const uint32_t notificationTime(0);
    2002             : 
    2003           0 :   if (input_file_player_->StartPlayingFile(
    2004             :           fileName, loop, startPosition, volumeScaling, notificationTime,
    2005           0 :           stopPosition, (const CodecInst*)codecInst) != 0) {
    2006           0 :     _engineStatisticsPtr->SetLastError(
    2007             :         VE_BAD_FILE, kTraceError,
    2008           0 :         "StartPlayingFile() failed to start file playout");
    2009           0 :     input_file_player_->StopPlayingFile();
    2010           0 :     input_file_player_.reset();
    2011           0 :     return -1;
    2012             :   }
    2013           0 :   input_file_player_->RegisterModuleFileCallback(this);
    2014           0 :   channel_state_.SetInputFilePlaying(true);
    2015             : 
    2016           0 :   return 0;
    2017             : }
    2018             : 
    2019           0 : int Channel::StartPlayingFileAsMicrophone(InStream* stream,
    2020             :                                           FileFormats format,
    2021             :                                           int startPosition,
    2022             :                                           float volumeScaling,
    2023             :                                           int stopPosition,
    2024             :                                           const CodecInst* codecInst) {
    2025             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2026             :                "Channel::StartPlayingFileAsMicrophone(format=%d, "
    2027             :                "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)",
    2028             :                format, volumeScaling, startPosition, stopPosition);
    2029             : 
    2030           0 :   if (stream == NULL) {
    2031           0 :     _engineStatisticsPtr->SetLastError(
    2032             :         VE_BAD_FILE, kTraceError,
    2033           0 :         "StartPlayingFileAsMicrophone NULL as input stream");
    2034           0 :     return -1;
    2035             :   }
    2036             : 
    2037           0 :   rtc::CritScope cs(&_fileCritSect);
    2038             : 
    2039           0 :   if (channel_state_.Get().input_file_playing) {
    2040           0 :     _engineStatisticsPtr->SetLastError(
    2041             :         VE_ALREADY_PLAYING, kTraceWarning,
    2042           0 :         "StartPlayingFileAsMicrophone() is playing");
    2043           0 :     return 0;
    2044             :   }
    2045             : 
    2046             :   // Destroy the old instance
    2047           0 :   if (input_file_player_) {
    2048           0 :     input_file_player_->RegisterModuleFileCallback(NULL);
    2049           0 :     input_file_player_.reset();
    2050             :   }
    2051             : 
    2052             :   // Create the instance
    2053           0 :   input_file_player_ = FilePlayer::CreateFilePlayer(_inputFilePlayerId,
    2054           0 :                                                     (const FileFormats)format);
    2055             : 
    2056           0 :   if (!input_file_player_) {
    2057           0 :     _engineStatisticsPtr->SetLastError(
    2058             :         VE_INVALID_ARGUMENT, kTraceError,
    2059           0 :         "StartPlayingInputFile() filePlayer format isnot correct");
    2060           0 :     return -1;
    2061             :   }
    2062             : 
    2063           0 :   const uint32_t notificationTime(0);
    2064             : 
    2065           0 :   if (input_file_player_->StartPlayingFile(stream, startPosition, volumeScaling,
    2066             :                                            notificationTime, stopPosition,
    2067           0 :                                            codecInst) != 0) {
    2068           0 :     _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
    2069             :                                        "StartPlayingFile() failed to start "
    2070           0 :                                        "file playout");
    2071           0 :     input_file_player_->StopPlayingFile();
    2072           0 :     input_file_player_.reset();
    2073           0 :     return -1;
    2074             :   }
    2075             : 
    2076           0 :   input_file_player_->RegisterModuleFileCallback(this);
    2077           0 :   channel_state_.SetInputFilePlaying(true);
    2078             : 
    2079           0 :   return 0;
    2080             : }
    2081             : 
    2082           0 : int Channel::StopPlayingFileAsMicrophone() {
    2083             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2084             :                "Channel::StopPlayingFileAsMicrophone()");
    2085             : 
    2086           0 :   rtc::CritScope cs(&_fileCritSect);
    2087             : 
    2088           0 :   if (!channel_state_.Get().input_file_playing) {
    2089           0 :     return 0;
    2090             :   }
    2091             : 
    2092           0 :   if (input_file_player_->StopPlayingFile() != 0) {
    2093           0 :     _engineStatisticsPtr->SetLastError(
    2094             :         VE_STOP_RECORDING_FAILED, kTraceError,
    2095           0 :         "StopPlayingFile() could not stop playing");
    2096           0 :     return -1;
    2097             :   }
    2098           0 :   input_file_player_->RegisterModuleFileCallback(NULL);
    2099           0 :   input_file_player_.reset();
    2100           0 :   channel_state_.SetInputFilePlaying(false);
    2101             : 
    2102           0 :   return 0;
    2103             : }
    2104             : 
    2105           0 : int Channel::IsPlayingFileAsMicrophone() const {
    2106           0 :   return channel_state_.Get().input_file_playing;
    2107             : }
    2108             : 
    2109           0 : int Channel::StartRecordingPlayout(const char* fileName,
    2110             :                                    const CodecInst* codecInst) {
    2111             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2112             :                "Channel::StartRecordingPlayout(fileName=%s)", fileName);
    2113             : 
    2114           0 :   if (_outputFileRecording) {
    2115             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
    2116             :                  "StartRecordingPlayout() is already recording");
    2117           0 :     return 0;
    2118             :   }
    2119             : 
    2120             :   FileFormats format;
    2121           0 :   const uint32_t notificationTime(0);  // Not supported in VoE
    2122           0 :   CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000};
    2123             : 
    2124           0 :   if ((codecInst != NULL) &&
    2125           0 :       ((codecInst->channels < 1) || (codecInst->channels > 2))) {
    2126           0 :     _engineStatisticsPtr->SetLastError(
    2127             :         VE_BAD_ARGUMENT, kTraceError,
    2128           0 :         "StartRecordingPlayout() invalid compression");
    2129           0 :     return (-1);
    2130             :   }
    2131           0 :   if (codecInst == NULL) {
    2132           0 :     format = kFileFormatPcm16kHzFile;
    2133           0 :     codecInst = &dummyCodec;
    2134           0 :   } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) ||
    2135           0 :              (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) ||
    2136           0 :              (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) {
    2137           0 :     format = kFileFormatWavFile;
    2138             :   } else {
    2139           0 :     format = kFileFormatCompressedFile;
    2140             :   }
    2141             : 
    2142           0 :   rtc::CritScope cs(&_fileCritSect);
    2143             : 
    2144             :   // Destroy the old instance
    2145           0 :   if (output_file_recorder_) {
    2146           0 :     output_file_recorder_->RegisterModuleFileCallback(NULL);
    2147           0 :     output_file_recorder_.reset();
    2148             :   }
    2149             : 
    2150           0 :   output_file_recorder_ = FileRecorder::CreateFileRecorder(
    2151           0 :       _outputFileRecorderId, (const FileFormats)format);
    2152           0 :   if (!output_file_recorder_) {
    2153           0 :     _engineStatisticsPtr->SetLastError(
    2154             :         VE_INVALID_ARGUMENT, kTraceError,
    2155           0 :         "StartRecordingPlayout() fileRecorder format isnot correct");
    2156           0 :     return -1;
    2157             :   }
    2158             : 
    2159           0 :   if (output_file_recorder_->StartRecordingAudioFile(
    2160           0 :           fileName, (const CodecInst&)*codecInst, notificationTime) != 0) {
    2161           0 :     _engineStatisticsPtr->SetLastError(
    2162             :         VE_BAD_FILE, kTraceError,
    2163           0 :         "StartRecordingAudioFile() failed to start file recording");
    2164           0 :     output_file_recorder_->StopRecording();
    2165           0 :     output_file_recorder_.reset();
    2166           0 :     return -1;
    2167             :   }
    2168           0 :   output_file_recorder_->RegisterModuleFileCallback(this);
    2169           0 :   _outputFileRecording = true;
    2170             : 
    2171           0 :   return 0;
    2172             : }
    2173             : 
    2174           0 : int Channel::StartRecordingPlayout(OutStream* stream,
    2175             :                                    const CodecInst* codecInst) {
    2176             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2177             :                "Channel::StartRecordingPlayout()");
    2178             : 
    2179           0 :   if (_outputFileRecording) {
    2180             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, -1),
    2181             :                  "StartRecordingPlayout() is already recording");
    2182           0 :     return 0;
    2183             :   }
    2184             : 
    2185             :   FileFormats format;
    2186           0 :   const uint32_t notificationTime(0);  // Not supported in VoE
    2187           0 :   CodecInst dummyCodec = {100, "L16", 16000, 320, 1, 320000};
    2188             : 
    2189           0 :   if (codecInst != NULL && codecInst->channels != 1) {
    2190           0 :     _engineStatisticsPtr->SetLastError(
    2191             :         VE_BAD_ARGUMENT, kTraceError,
    2192           0 :         "StartRecordingPlayout() invalid compression");
    2193           0 :     return (-1);
    2194             :   }
    2195           0 :   if (codecInst == NULL) {
    2196           0 :     format = kFileFormatPcm16kHzFile;
    2197           0 :     codecInst = &dummyCodec;
    2198           0 :   } else if ((STR_CASE_CMP(codecInst->plname, "L16") == 0) ||
    2199           0 :              (STR_CASE_CMP(codecInst->plname, "PCMU") == 0) ||
    2200           0 :              (STR_CASE_CMP(codecInst->plname, "PCMA") == 0)) {
    2201           0 :     format = kFileFormatWavFile;
    2202             :   } else {
    2203           0 :     format = kFileFormatCompressedFile;
    2204             :   }
    2205             : 
    2206           0 :   rtc::CritScope cs(&_fileCritSect);
    2207             : 
    2208             :   // Destroy the old instance
    2209           0 :   if (output_file_recorder_) {
    2210           0 :     output_file_recorder_->RegisterModuleFileCallback(NULL);
    2211           0 :     output_file_recorder_.reset();
    2212             :   }
    2213             : 
    2214           0 :   output_file_recorder_ = FileRecorder::CreateFileRecorder(
    2215           0 :       _outputFileRecorderId, (const FileFormats)format);
    2216           0 :   if (!output_file_recorder_) {
    2217           0 :     _engineStatisticsPtr->SetLastError(
    2218             :         VE_INVALID_ARGUMENT, kTraceError,
    2219           0 :         "StartRecordingPlayout() fileRecorder format isnot correct");
    2220           0 :     return -1;
    2221             :   }
    2222             : 
    2223           0 :   if (output_file_recorder_->StartRecordingAudioFile(stream, *codecInst,
    2224           0 :                                                      notificationTime) != 0) {
    2225           0 :     _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
    2226             :                                        "StartRecordingPlayout() failed to "
    2227           0 :                                        "start file recording");
    2228           0 :     output_file_recorder_->StopRecording();
    2229           0 :     output_file_recorder_.reset();
    2230           0 :     return -1;
    2231             :   }
    2232             : 
    2233           0 :   output_file_recorder_->RegisterModuleFileCallback(this);
    2234           0 :   _outputFileRecording = true;
    2235             : 
    2236           0 :   return 0;
    2237             : }
    2238             : 
    2239           0 : int Channel::StopRecordingPlayout() {
    2240             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, -1),
    2241             :                "Channel::StopRecordingPlayout()");
    2242             : 
    2243           0 :   if (!_outputFileRecording) {
    2244             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, -1),
    2245             :                  "StopRecordingPlayout() isnot recording");
    2246           0 :     return -1;
    2247             :   }
    2248             : 
    2249           0 :   rtc::CritScope cs(&_fileCritSect);
    2250             : 
    2251           0 :   if (output_file_recorder_->StopRecording() != 0) {
    2252           0 :     _engineStatisticsPtr->SetLastError(
    2253             :         VE_STOP_RECORDING_FAILED, kTraceError,
    2254           0 :         "StopRecording() could not stop recording");
    2255           0 :     return (-1);
    2256             :   }
    2257           0 :   output_file_recorder_->RegisterModuleFileCallback(NULL);
    2258           0 :   output_file_recorder_.reset();
    2259           0 :   _outputFileRecording = false;
    2260             : 
    2261           0 :   return 0;
    2262             : }
    2263             : 
    2264           0 : void Channel::SetMixWithMicStatus(bool mix) {
    2265           0 :   rtc::CritScope cs(&_fileCritSect);
    2266           0 :   _mixFileWithMicrophone = mix;
    2267           0 : }
    2268             : 
    2269           0 : int Channel::GetSpeechOutputLevel(uint32_t& level) const {
    2270           0 :   int8_t currentLevel = _outputAudioLevel.Level();
    2271           0 :   level = static_cast<int32_t>(currentLevel);
    2272           0 :   return 0;
    2273             : }
    2274             : 
    2275           0 : int Channel::GetSpeechOutputLevelFullRange(uint32_t& level) const {
    2276           0 :   int16_t currentLevel = _outputAudioLevel.LevelFullRange();
    2277           0 :   level = static_cast<int32_t>(currentLevel);
    2278           0 :   return 0;
    2279             : }
    2280             : 
    2281           0 : int Channel::SetInputMute(bool enable) {
    2282           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2283             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2284             :                "Channel::SetMute(enable=%d)", enable);
    2285           0 :   input_mute_ = enable;
    2286           0 :   return 0;
    2287             : }
    2288             : 
    2289           0 : bool Channel::InputMute() const {
    2290           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2291           0 :   return input_mute_;
    2292             : }
    2293             : 
    2294           0 : int Channel::SetOutputVolumePan(float left, float right) {
    2295           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2296             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2297             :                "Channel::SetOutputVolumePan()");
    2298           0 :   _panLeft = left;
    2299           0 :   _panRight = right;
    2300           0 :   return 0;
    2301             : }
    2302             : 
    2303           0 : int Channel::GetOutputVolumePan(float& left, float& right) const {
    2304           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2305           0 :   left = _panLeft;
    2306           0 :   right = _panRight;
    2307           0 :   return 0;
    2308             : }
    2309             : 
    2310           0 : int Channel::SetChannelOutputVolumeScaling(float scaling) {
    2311           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2312             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2313             :                "Channel::SetChannelOutputVolumeScaling()");
    2314           0 :   _outputGain = scaling;
    2315           0 :   return 0;
    2316             : }
    2317             : 
    2318           0 : int Channel::GetChannelOutputVolumeScaling(float& scaling) const {
    2319           0 :   rtc::CritScope cs(&volume_settings_critsect_);
    2320           0 :   scaling = _outputGain;
    2321           0 :   return 0;
    2322             : }
    2323             : 
    2324           0 : int Channel::SendTelephoneEventOutband(int event, int duration_ms) {
    2325             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2326             :                "Channel::SendTelephoneEventOutband(...)");
    2327           0 :   RTC_DCHECK_LE(0, event);
    2328           0 :   RTC_DCHECK_GE(255, event);
    2329           0 :   RTC_DCHECK_LE(0, duration_ms);
    2330           0 :   RTC_DCHECK_GE(65535, duration_ms);
    2331           0 :   if (!Sending()) {
    2332           0 :     return -1;
    2333             :   }
    2334           0 :   if (_rtpRtcpModule->SendTelephoneEventOutband(
    2335           0 :       event, duration_ms, kTelephoneEventAttenuationdB) != 0) {
    2336           0 :     _engineStatisticsPtr->SetLastError(
    2337             :         VE_SEND_DTMF_FAILED, kTraceWarning,
    2338           0 :         "SendTelephoneEventOutband() failed to send event");
    2339           0 :     return -1;
    2340             :   }
    2341           0 :   return 0;
    2342             : }
    2343             : 
    2344           0 : int Channel::SetSendTelephoneEventPayloadType(int payload_type,
    2345             :                                               int payload_frequency) {
    2346             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2347             :                "Channel::SetSendTelephoneEventPayloadType()");
    2348           0 :   RTC_DCHECK_LE(0, payload_type);
    2349           0 :   RTC_DCHECK_GE(127, payload_type);
    2350           0 :   CodecInst codec = {0};
    2351           0 :   codec.pltype = payload_type;
    2352           0 :   codec.plfreq = payload_frequency;
    2353           0 :   memcpy(codec.plname, "telephone-event", 16);
    2354           0 :   if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    2355           0 :     _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
    2356           0 :     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
    2357           0 :       _engineStatisticsPtr->SetLastError(
    2358             :           VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    2359             :           "SetSendTelephoneEventPayloadType() failed to register send"
    2360           0 :           "payload type");
    2361           0 :       return -1;
    2362             :     }
    2363             :   }
    2364           0 :   return 0;
    2365             : }
    2366             : 
    2367           0 : int Channel::VoiceActivityIndicator(int& activity) {
    2368           0 :   activity = _sendFrameType;
    2369           0 :   return 0;
    2370             : }
    2371             : 
    2372           0 : int Channel::SetLocalSSRC(unsigned int ssrc) {
    2373             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2374             :                "Channel::SetLocalSSRC()");
    2375           0 :   if (channel_state_.Get().sending) {
    2376           0 :     _engineStatisticsPtr->SetLastError(VE_ALREADY_SENDING, kTraceError,
    2377           0 :                                        "SetLocalSSRC() already sending");
    2378           0 :     return -1;
    2379             :   }
    2380           0 :   _rtpRtcpModule->SetSSRC(ssrc);
    2381           0 :   return 0;
    2382             : }
    2383             : 
    2384           0 : int Channel::GetLocalSSRC(unsigned int& ssrc) {
    2385           0 :   ssrc = _rtpRtcpModule->SSRC();
    2386           0 :   return 0;
    2387             : }
    2388             : 
    2389           0 : int Channel::GetRemoteSSRC(unsigned int& ssrc) {
    2390           0 :   ssrc = rtp_receiver_->SSRC();
    2391           0 :   return 0;
    2392             : }
    2393             : 
    2394           0 : int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) {
    2395           0 :   _includeAudioLevelIndication = enable;
    2396           0 :   return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id);
    2397             : }
    2398             : 
    2399           0 : int Channel::SetReceiveAudioLevelIndicationStatus(bool enable,
    2400             :                                                   unsigned char id) {
    2401           0 :   rtp_header_parser_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
    2402           0 :   if (enable &&
    2403           0 :       !rtp_header_parser_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
    2404           0 :                                                       id)) {
    2405           0 :     return -1;
    2406             :   }
    2407           0 :   return 0;
    2408             : }
    2409             : 
    2410           0 : void Channel::EnableSendTransportSequenceNumber(int id) {
    2411             :   int ret =
    2412           0 :       SetSendRtpHeaderExtension(true, kRtpExtensionTransportSequenceNumber, id);
    2413           0 :   RTC_DCHECK_EQ(0, ret);
    2414           0 : }
    2415             : 
    2416           0 : void Channel::EnableReceiveTransportSequenceNumber(int id) {
    2417           0 :   rtp_header_parser_->DeregisterRtpHeaderExtension(
    2418           0 :       kRtpExtensionTransportSequenceNumber);
    2419           0 :   bool ret = rtp_header_parser_->RegisterRtpHeaderExtension(
    2420           0 :       kRtpExtensionTransportSequenceNumber, id);
    2421           0 :   RTC_DCHECK(ret);
    2422           0 : }
    2423             : 
    2424           0 : void Channel::RegisterSenderCongestionControlObjects(
    2425             :     RtpPacketSender* rtp_packet_sender,
    2426             :     TransportFeedbackObserver* transport_feedback_observer,
    2427             :     PacketRouter* packet_router) {
    2428           0 :   RTC_DCHECK(rtp_packet_sender);
    2429           0 :   RTC_DCHECK(transport_feedback_observer);
    2430           0 :   RTC_DCHECK(packet_router && !packet_router_);
    2431           0 :   feedback_observer_proxy_->SetTransportFeedbackObserver(
    2432           0 :       transport_feedback_observer);
    2433           0 :   seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
    2434           0 :   rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
    2435           0 :   _rtpRtcpModule->SetStorePacketsStatus(true, 600);
    2436           0 :   packet_router->AddRtpModule(_rtpRtcpModule.get());
    2437           0 :   packet_router_ = packet_router;
    2438           0 : }
    2439             : 
    2440           0 : void Channel::RegisterReceiverCongestionControlObjects(
    2441             :     PacketRouter* packet_router) {
    2442           0 :   RTC_DCHECK(packet_router && !packet_router_);
    2443           0 :   packet_router->AddRtpModule(_rtpRtcpModule.get());
    2444           0 :   packet_router_ = packet_router;
    2445           0 : }
    2446             : 
    2447           0 : void Channel::ResetCongestionControlObjects() {
    2448           0 :   RTC_DCHECK(packet_router_);
    2449           0 :   _rtpRtcpModule->SetStorePacketsStatus(false, 600);
    2450           0 :   feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr);
    2451           0 :   seq_num_allocator_proxy_->SetSequenceNumberAllocator(nullptr);
    2452           0 :   packet_router_->RemoveRtpModule(_rtpRtcpModule.get());
    2453           0 :   packet_router_ = nullptr;
    2454           0 :   rtp_packet_sender_proxy_->SetPacketSender(nullptr);
    2455           0 : }
    2456             : 
    2457           0 : void Channel::SetRTCPStatus(bool enable) {
    2458             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2459             :                "Channel::SetRTCPStatus()");
    2460           0 :   _rtpRtcpModule->SetRTCPStatus(enable ? RtcpMode::kCompound : RtcpMode::kOff);
    2461           0 : }
    2462             : 
    2463           0 : int Channel::GetRTCPStatus(bool& enabled) {
    2464           0 :   RtcpMode method = _rtpRtcpModule->RTCP();
    2465           0 :   enabled = (method != RtcpMode::kOff);
    2466           0 :   return 0;
    2467             : }
    2468             : 
    2469           0 : int Channel::SetRTCP_CNAME(const char cName[256]) {
    2470             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2471             :                "Channel::SetRTCP_CNAME()");
    2472           0 :   if (_rtpRtcpModule->SetCNAME(cName) != 0) {
    2473           0 :     _engineStatisticsPtr->SetLastError(
    2474             :         VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    2475           0 :         "SetRTCP_CNAME() failed to set RTCP CNAME");
    2476           0 :     return -1;
    2477             :   }
    2478           0 :   return 0;
    2479             : }
    2480             : 
    2481           0 : int Channel::GetRemoteRTCP_CNAME(char cName[256]) {
    2482           0 :   if (cName == NULL) {
    2483           0 :     _engineStatisticsPtr->SetLastError(
    2484             :         VE_INVALID_ARGUMENT, kTraceError,
    2485           0 :         "GetRemoteRTCP_CNAME() invalid CNAME input buffer");
    2486           0 :     return -1;
    2487             :   }
    2488             :   char cname[RTCP_CNAME_SIZE];
    2489           0 :   const uint32_t remoteSSRC = rtp_receiver_->SSRC();
    2490           0 :   if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0) {
    2491           0 :     _engineStatisticsPtr->SetLastError(
    2492             :         VE_CANNOT_RETRIEVE_CNAME, kTraceError,
    2493           0 :         "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME");
    2494           0 :     return -1;
    2495             :   }
    2496           0 :   strcpy(cName, cname);
    2497           0 :   return 0;
    2498             : }
    2499             : 
    2500           0 : int Channel::GetRemoteRTCPData(unsigned int& NTPHigh,
    2501             :                                unsigned int& NTPLow,
    2502             :                                unsigned int& timestamp,
    2503             :                                unsigned int& playoutTimestamp,
    2504             :                                unsigned int* jitter,
    2505             :                                unsigned short* fractionLost) {
    2506             :   // --- Information from sender info in received Sender Reports
    2507             : 
    2508             :   RTCPSenderInfo senderInfo;
    2509           0 :   if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0) {
    2510           0 :     _engineStatisticsPtr->SetLastError(
    2511             :         VE_RTP_RTCP_MODULE_ERROR, kTraceError,
    2512             :         "GetRemoteRTCPData() failed to retrieve sender info for remote "
    2513           0 :         "side");
    2514           0 :     return -1;
    2515             :   }
    2516             : 
    2517             :   // We only utilize 12 out of 20 bytes in the sender info (ignores packet
    2518             :   // and octet count)
    2519           0 :   NTPHigh = senderInfo.NTPseconds;
    2520           0 :   NTPLow = senderInfo.NTPfraction;
    2521           0 :   timestamp = senderInfo.RTPtimeStamp;
    2522             : 
    2523             :   // --- Locally derived information
    2524             : 
    2525             :   // This value is updated on each incoming RTCP packet (0 when no packet
    2526             :   // has been received)
    2527           0 :   playoutTimestamp = playout_timestamp_rtcp_;
    2528             : 
    2529           0 :   if (NULL != jitter || NULL != fractionLost) {
    2530             :     // Get all RTCP receiver report blocks that have been received on this
    2531             :     // channel. If we receive RTP packets from a remote source we know the
    2532             :     // remote SSRC and use the report block from him.
    2533             :     // Otherwise use the first report block.
    2534           0 :     std::vector<RTCPReportBlock> remote_stats;
    2535           0 :     if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 ||
    2536           0 :         remote_stats.empty()) {
    2537             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    2538             :                    "GetRemoteRTCPData() failed to measure statistics due"
    2539             :                    " to lack of received RTP and/or RTCP packets");
    2540           0 :       return -1;
    2541             :     }
    2542             : 
    2543           0 :     uint32_t remoteSSRC = rtp_receiver_->SSRC();
    2544           0 :     std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin();
    2545           0 :     for (; it != remote_stats.end(); ++it) {
    2546           0 :       if (it->remoteSSRC == remoteSSRC)
    2547           0 :         break;
    2548             :     }
    2549             : 
    2550           0 :     if (it == remote_stats.end()) {
    2551             :       // If we have not received any RTCP packets from this SSRC it probably
    2552             :       // means that we have not received any RTP packets.
    2553             :       // Use the first received report block instead.
    2554           0 :       it = remote_stats.begin();
    2555           0 :       remoteSSRC = it->remoteSSRC;
    2556             :     }
    2557             : 
    2558           0 :     if (jitter) {
    2559           0 :       *jitter = it->jitter;
    2560             :     }
    2561             : 
    2562           0 :     if (fractionLost) {
    2563           0 :       *fractionLost = it->fractionLost;
    2564             :     }
    2565             :   }
    2566           0 :   return 0;
    2567             : }
    2568             : 
    2569           0 : int Channel::SendApplicationDefinedRTCPPacket(
    2570             :     unsigned char subType,
    2571             :     unsigned int name,
    2572             :     const char* data,
    2573             :     unsigned short dataLengthInBytes) {
    2574             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2575             :                "Channel::SendApplicationDefinedRTCPPacket()");
    2576           0 :   if (!channel_state_.Get().sending) {
    2577           0 :     _engineStatisticsPtr->SetLastError(
    2578             :         VE_NOT_SENDING, kTraceError,
    2579           0 :         "SendApplicationDefinedRTCPPacket() not sending");
    2580           0 :     return -1;
    2581             :   }
    2582           0 :   if (NULL == data) {
    2583           0 :     _engineStatisticsPtr->SetLastError(
    2584             :         VE_INVALID_ARGUMENT, kTraceError,
    2585           0 :         "SendApplicationDefinedRTCPPacket() invalid data value");
    2586           0 :     return -1;
    2587             :   }
    2588           0 :   if (dataLengthInBytes % 4 != 0) {
    2589           0 :     _engineStatisticsPtr->SetLastError(
    2590             :         VE_INVALID_ARGUMENT, kTraceError,
    2591           0 :         "SendApplicationDefinedRTCPPacket() invalid length value");
    2592           0 :     return -1;
    2593             :   }
    2594           0 :   RtcpMode status = _rtpRtcpModule->RTCP();
    2595           0 :   if (status == RtcpMode::kOff) {
    2596           0 :     _engineStatisticsPtr->SetLastError(
    2597             :         VE_RTCP_ERROR, kTraceError,
    2598           0 :         "SendApplicationDefinedRTCPPacket() RTCP is disabled");
    2599           0 :     return -1;
    2600             :   }
    2601             : 
    2602             :   // Create and schedule the RTCP APP packet for transmission
    2603           0 :   if (_rtpRtcpModule->SetRTCPApplicationSpecificData(
    2604           0 :           subType, name, (const unsigned char*)data, dataLengthInBytes) != 0) {
    2605           0 :     _engineStatisticsPtr->SetLastError(
    2606             :         VE_SEND_ERROR, kTraceError,
    2607           0 :         "SendApplicationDefinedRTCPPacket() failed to send RTCP packet");
    2608           0 :     return -1;
    2609             :   }
    2610           0 :   return 0;
    2611             : }
    2612             : 
    2613           0 : int Channel::GetRTPStatistics(unsigned int& averageJitterMs,
    2614             :                               unsigned int& maxJitterMs,
    2615             :                               unsigned int& discardedPackets,
    2616             :                               unsigned int& cumulativeLost) {
    2617             :   // The jitter statistics is updated for each received RTP packet and is
    2618             :   // based on received packets.
    2619           0 :   if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) {
    2620             :     // If RTCP is off, there is no timed thread in the RTCP module regularly
    2621             :     // generating new stats, trigger the update manually here instead.
    2622             :     StreamStatistician* statistician =
    2623           0 :         rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
    2624           0 :     if (statistician) {
    2625             :       // Don't use returned statistics, use data from proxy instead so that
    2626             :       // max jitter can be fetched atomically.
    2627           0 :       RtcpStatistics s;
    2628           0 :       statistician->GetStatistics(&s, true);
    2629             :     }
    2630             :   }
    2631             : 
    2632           0 :   ChannelStatistics stats = statistics_proxy_->GetStats();
    2633           0 :   const int32_t playoutFrequency = audio_coding_->PlayoutFrequency();
    2634           0 :   if (playoutFrequency > 0) {
    2635             :     // Scale RTP statistics given the current playout frequency
    2636           0 :     maxJitterMs = stats.max_jitter / (playoutFrequency / 1000);
    2637           0 :     averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000);
    2638           0 :     cumulativeLost = stats.rtcp.cumulative_lost;
    2639             :   }
    2640             : 
    2641           0 :   discardedPackets = _numberOfDiscardedPackets;
    2642             : 
    2643           0 :   return 0;
    2644             : }
    2645             : 
    2646           0 : int Channel::GetRemoteRTCPReportBlocks(
    2647             :     std::vector<ReportBlock>* report_blocks) {
    2648           0 :   if (report_blocks == NULL) {
    2649           0 :     _engineStatisticsPtr->SetLastError(
    2650             :         VE_INVALID_ARGUMENT, kTraceError,
    2651           0 :         "GetRemoteRTCPReportBlock()s invalid report_blocks.");
    2652           0 :     return -1;
    2653             :   }
    2654             : 
    2655             :   // Get the report blocks from the latest received RTCP Sender or Receiver
    2656             :   // Report. Each element in the vector contains the sender's SSRC and a
    2657             :   // report block according to RFC 3550.
    2658           0 :   std::vector<RTCPReportBlock> rtcp_report_blocks;
    2659           0 :   if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) {
    2660           0 :     return -1;
    2661             :   }
    2662             : 
    2663           0 :   if (rtcp_report_blocks.empty())
    2664           0 :     return 0;
    2665             : 
    2666           0 :   std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin();
    2667           0 :   for (; it != rtcp_report_blocks.end(); ++it) {
    2668             :     ReportBlock report_block;
    2669           0 :     report_block.sender_SSRC = it->remoteSSRC;
    2670           0 :     report_block.source_SSRC = it->sourceSSRC;
    2671           0 :     report_block.fraction_lost = it->fractionLost;
    2672           0 :     report_block.cumulative_num_packets_lost = it->cumulativeLost;
    2673           0 :     report_block.extended_highest_sequence_number = it->extendedHighSeqNum;
    2674           0 :     report_block.interarrival_jitter = it->jitter;
    2675           0 :     report_block.last_SR_timestamp = it->lastSR;
    2676           0 :     report_block.delay_since_last_SR = it->delaySinceLastSR;
    2677           0 :     report_blocks->push_back(report_block);
    2678             :   }
    2679           0 :   return 0;
    2680             : }
    2681             : 
    2682           0 : int Channel::GetRTPStatistics(CallStatistics& stats) {
    2683             :   // --- RtcpStatistics
    2684             :   // GetStatistics() grabs the stream_lock_ inside the object
    2685             :   // rtp_receiver_->SSRC grabs a lock too.
    2686             : 
    2687             :   // The jitter statistics is updated for each received RTP packet and is
    2688             :   // based on received packets.
    2689           0 :   RtcpStatistics statistics;
    2690             :   StreamStatistician* statistician =
    2691           0 :     rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
    2692           0 :   if (statistician) {
    2693           0 :     statistician->GetStatistics(&statistics,
    2694           0 :                                 _rtpRtcpModule->RTCP() == RtcpMode::kOff);
    2695             :   }
    2696             : 
    2697           0 :   stats.fractionLost = statistics.fraction_lost;
    2698           0 :   stats.cumulativeLost = statistics.cumulative_lost;
    2699           0 :   stats.extendedMax = statistics.extended_max_sequence_number;
    2700           0 :   stats.jitterSamples = statistics.jitter;
    2701             : 
    2702             :   // --- RTT
    2703           0 :   stats.rttMs = GetRTT(true);
    2704             : 
    2705             :   // --- Data counters
    2706             : 
    2707           0 :   size_t bytesSent(0);
    2708           0 :   uint32_t packetsSent(0);
    2709           0 :   size_t bytesReceived(0);
    2710           0 :   uint32_t packetsReceived(0);
    2711             : 
    2712           0 :   if (statistician) {
    2713           0 :     statistician->GetDataCounters(&bytesReceived, &packetsReceived);
    2714             :   }
    2715             : 
    2716           0 :   if (_rtpRtcpModule->DataCountersRTP(&bytesSent, &packetsSent) != 0) {
    2717             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    2718             :                  "GetRTPStatistics() failed to retrieve RTP datacounters =>"
    2719             :                  " output will not be complete");
    2720             :   }
    2721             : 
    2722           0 :   stats.bytesSent = bytesSent;
    2723           0 :   stats.packetsSent = packetsSent;
    2724           0 :   stats.bytesReceived = bytesReceived;
    2725           0 :   stats.packetsReceived = packetsReceived;
    2726             : 
    2727             :   // --- Timestamps
    2728             :   {
    2729           0 :     rtc::CritScope lock(&ts_stats_lock_);
    2730           0 :     stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_;
    2731             :   }
    2732           0 :   return 0;
    2733             : }
    2734             : 
    2735           0 : int Channel::GetRTCPPacketTypeCounters(RtcpPacketTypeCounter& stats) {
    2736           0 :   if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) {
    2737           0 :     return -1;
    2738             :   }
    2739           0 :   statistics_proxy_->GetPacketTypeCounter(stats);
    2740           0 :   return 0;
    2741             : }
    2742             : 
    2743           0 : int Channel::SetCodecFECStatus(bool enable) {
    2744             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2745             :                "Channel::SetCodecFECStatus()");
    2746             : 
    2747           0 :   if (!codec_manager_.SetCodecFEC(enable) ||
    2748           0 :       !codec_manager_.MakeEncoder(&rent_a_codec_, audio_coding_.get())) {
    2749           0 :     _engineStatisticsPtr->SetLastError(
    2750             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    2751           0 :         "SetCodecFECStatus() failed to set FEC state");
    2752           0 :     return -1;
    2753             :   }
    2754           0 :   return 0;
    2755             : }
    2756             : 
    2757           0 : bool Channel::GetCodecFECStatus() {
    2758           0 :   return codec_manager_.GetStackParams()->use_codec_fec;
    2759             : }
    2760             : 
    2761           0 : void Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) {
    2762             :   // None of these functions can fail.
    2763             :   // If pacing is enabled we always store packets.
    2764           0 :   if (!pacing_enabled_)
    2765           0 :     _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets);
    2766           0 :   rtp_receive_statistics_->SetMaxReorderingThreshold(maxNumberOfPackets);
    2767           0 :   if (enable)
    2768           0 :     audio_coding_->EnableNack(maxNumberOfPackets);
    2769             :   else
    2770           0 :     audio_coding_->DisableNack();
    2771           0 : }
    2772             : 
    2773             : // Called when we are missing one or more packets.
    2774           0 : int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) {
    2775           0 :   return _rtpRtcpModule->SendNACK(sequence_numbers, length);
    2776             : }
    2777             : 
    2778           0 : uint32_t Channel::Demultiplex(const AudioFrame& audioFrame) {
    2779             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    2780             :                "Channel::Demultiplex()");
    2781           0 :   _audioFrame.CopyFrom(audioFrame);
    2782           0 :   _audioFrame.id_ = _channelId;
    2783           0 :   return 0;
    2784             : }
    2785             : 
    2786           0 : void Channel::Demultiplex(const int16_t* audio_data,
    2787             :                           int sample_rate,
    2788             :                           size_t number_of_frames,
    2789             :                           size_t number_of_channels) {
    2790             :   CodecInst codec;
    2791           0 :   GetSendCodec(codec);
    2792             : 
    2793             :   // Never upsample or upmix the capture signal here. This should be done at the
    2794             :   // end of the send chain.
    2795           0 :   _audioFrame.sample_rate_hz_ = std::min(codec.plfreq, sample_rate);
    2796           0 :   _audioFrame.num_channels_ = std::min(number_of_channels, codec.channels);
    2797           0 :   RemixAndResample(audio_data, number_of_frames, number_of_channels,
    2798           0 :                    sample_rate, &input_resampler_, &_audioFrame);
    2799           0 : }
    2800             : 
    2801           0 : uint32_t Channel::PrepareEncodeAndSend(int mixingFrequency) {
    2802             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    2803             :                "Channel::PrepareEncodeAndSend()");
    2804             : 
    2805           0 :   if (_audioFrame.samples_per_channel_ == 0) {
    2806             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    2807             :                  "Channel::PrepareEncodeAndSend() invalid audio frame");
    2808           0 :     return 0xFFFFFFFF;
    2809             :   }
    2810             : 
    2811           0 :   if (channel_state_.Get().input_file_playing) {
    2812           0 :     MixOrReplaceAudioWithFile(mixingFrequency);
    2813             :   }
    2814             : 
    2815           0 :   bool is_muted = InputMute();  // Cache locally as InputMute() takes a lock.
    2816           0 :   AudioFrameOperations::Mute(&_audioFrame, previous_frame_muted_, is_muted);
    2817             : 
    2818           0 :   if (channel_state_.Get().input_external_media) {
    2819           0 :     rtc::CritScope cs(&_callbackCritSect);
    2820           0 :     const bool isStereo = (_audioFrame.num_channels_ == 2);
    2821           0 :     if (_inputExternalMediaCallbackPtr) {
    2822           0 :       _inputExternalMediaCallbackPtr->Process(
    2823             :           _channelId, kRecordingPerChannel, (int16_t*)_audioFrame.data_,
    2824             :           _audioFrame.samples_per_channel_, _audioFrame.sample_rate_hz_,
    2825           0 :           isStereo);
    2826             :     }
    2827             :   }
    2828             : 
    2829           0 :   if (_includeAudioLevelIndication) {
    2830             :     size_t length =
    2831           0 :         _audioFrame.samples_per_channel_ * _audioFrame.num_channels_;
    2832           0 :     RTC_CHECK_LE(length, sizeof(_audioFrame.data_));
    2833           0 :     if (is_muted && previous_frame_muted_) {
    2834           0 :       rms_level_.AnalyzeMuted(length);
    2835             :     } else {
    2836           0 :       rms_level_.Analyze(
    2837           0 :           rtc::ArrayView<const int16_t>(_audioFrame.data_, length));
    2838             :     }
    2839             :   }
    2840           0 :   previous_frame_muted_ = is_muted;
    2841             : 
    2842           0 :   return 0;
    2843             : }
    2844             : 
    2845           0 : uint32_t Channel::EncodeAndSend() {
    2846             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    2847             :                "Channel::EncodeAndSend()");
    2848             : 
    2849           0 :   assert(_audioFrame.num_channels_ <= 2);
    2850           0 :   if (_audioFrame.samples_per_channel_ == 0) {
    2851             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    2852             :                  "Channel::EncodeAndSend() invalid audio frame");
    2853           0 :     return 0xFFFFFFFF;
    2854             :   }
    2855             : 
    2856           0 :   _audioFrame.id_ = _channelId;
    2857             : 
    2858             :   // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz.
    2859             : 
    2860             :   // The ACM resamples internally.
    2861           0 :   _audioFrame.timestamp_ = _timeStamp;
    2862             :   // This call will trigger AudioPacketizationCallback::SendData if encoding
    2863             :   // is done and payload is ready for packetization and transmission.
    2864             :   // Otherwise, it will return without invoking the callback.
    2865           0 :   if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0) {
    2866             :     WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId, _channelId),
    2867             :                  "Channel::EncodeAndSend() ACM encoding failed");
    2868           0 :     return 0xFFFFFFFF;
    2869             :   }
    2870             : 
    2871           0 :   _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_);
    2872           0 :   return 0;
    2873             : }
    2874             : 
    2875           0 : void Channel::set_associate_send_channel(const ChannelOwner& channel) {
    2876           0 :   RTC_DCHECK(!channel.channel() ||
    2877           0 :              channel.channel()->ChannelId() != _channelId);
    2878           0 :   rtc::CritScope lock(&assoc_send_channel_lock_);
    2879           0 :   associate_send_channel_ = channel;
    2880           0 : }
    2881             : 
    2882           0 : void Channel::DisassociateSendChannel(int channel_id) {
    2883           0 :   rtc::CritScope lock(&assoc_send_channel_lock_);
    2884           0 :   Channel* channel = associate_send_channel_.channel();
    2885           0 :   if (channel && channel->ChannelId() == channel_id) {
    2886             :     // If this channel is associated with a send channel of the specified
    2887             :     // Channel ID, disassociate with it.
    2888           0 :     ChannelOwner ref(NULL);
    2889           0 :     associate_send_channel_ = ref;
    2890             :   }
    2891           0 : }
    2892             : 
    2893           0 : void Channel::SetRtcEventLog(RtcEventLog* event_log) {
    2894           0 :   event_log_proxy_->SetEventLog(event_log);
    2895           0 : }
    2896             : 
    2897           0 : void Channel::SetRtcpRttStats(RtcpRttStats* rtcp_rtt_stats) {
    2898           0 :   rtcp_rtt_stats_proxy_->SetRtcpRttStats(rtcp_rtt_stats);
    2899           0 : }
    2900             : 
    2901           0 : void Channel::UpdateOverheadForEncoder() {
    2902           0 :   audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
    2903           0 :     if (*encoder) {
    2904           0 :       (*encoder)->OnReceivedOverhead(transport_overhead_per_packet_ +
    2905           0 :                                      rtp_overhead_per_packet_);
    2906             :     }
    2907           0 :   });
    2908           0 : }
    2909             : 
    2910           0 : void Channel::SetTransportOverhead(size_t transport_overhead_per_packet) {
    2911           0 :   transport_overhead_per_packet_ = transport_overhead_per_packet;
    2912           0 :   UpdateOverheadForEncoder();
    2913           0 : }
    2914             : 
    2915           0 : void Channel::OnOverheadChanged(size_t overhead_bytes_per_packet) {
    2916           0 :   rtp_overhead_per_packet_ = overhead_bytes_per_packet;
    2917           0 :   UpdateOverheadForEncoder();
    2918           0 : }
    2919             : 
    2920           0 : int Channel::RegisterExternalMediaProcessing(ProcessingTypes type,
    2921             :                                              VoEMediaProcess& processObject) {
    2922             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2923             :                "Channel::RegisterExternalMediaProcessing()");
    2924             : 
    2925           0 :   rtc::CritScope cs(&_callbackCritSect);
    2926             : 
    2927           0 :   if (kPlaybackPerChannel == type) {
    2928           0 :     if (_outputExternalMediaCallbackPtr) {
    2929           0 :       _engineStatisticsPtr->SetLastError(
    2930             :           VE_INVALID_OPERATION, kTraceError,
    2931             :           "Channel::RegisterExternalMediaProcessing() "
    2932           0 :           "output external media already enabled");
    2933           0 :       return -1;
    2934             :     }
    2935           0 :     _outputExternalMediaCallbackPtr = &processObject;
    2936           0 :     _outputExternalMedia = true;
    2937           0 :   } else if (kRecordingPerChannel == type) {
    2938           0 :     if (_inputExternalMediaCallbackPtr) {
    2939           0 :       _engineStatisticsPtr->SetLastError(
    2940             :           VE_INVALID_OPERATION, kTraceError,
    2941             :           "Channel::RegisterExternalMediaProcessing() "
    2942           0 :           "output external media already enabled");
    2943           0 :       return -1;
    2944             :     }
    2945           0 :     _inputExternalMediaCallbackPtr = &processObject;
    2946           0 :     channel_state_.SetInputExternalMedia(true);
    2947             :   }
    2948           0 :   return 0;
    2949             : }
    2950             : 
    2951           0 : int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type) {
    2952             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2953             :                "Channel::DeRegisterExternalMediaProcessing()");
    2954             : 
    2955           0 :   rtc::CritScope cs(&_callbackCritSect);
    2956             : 
    2957           0 :   if (kPlaybackPerChannel == type) {
    2958           0 :     if (!_outputExternalMediaCallbackPtr) {
    2959           0 :       _engineStatisticsPtr->SetLastError(
    2960             :           VE_INVALID_OPERATION, kTraceWarning,
    2961             :           "Channel::DeRegisterExternalMediaProcessing() "
    2962           0 :           "output external media already disabled");
    2963           0 :       return 0;
    2964             :     }
    2965           0 :     _outputExternalMedia = false;
    2966           0 :     _outputExternalMediaCallbackPtr = NULL;
    2967           0 :   } else if (kRecordingPerChannel == type) {
    2968           0 :     if (!_inputExternalMediaCallbackPtr) {
    2969           0 :       _engineStatisticsPtr->SetLastError(
    2970             :           VE_INVALID_OPERATION, kTraceWarning,
    2971             :           "Channel::DeRegisterExternalMediaProcessing() "
    2972           0 :           "input external media already disabled");
    2973           0 :       return 0;
    2974             :     }
    2975           0 :     channel_state_.SetInputExternalMedia(false);
    2976           0 :     _inputExternalMediaCallbackPtr = NULL;
    2977             :   }
    2978             : 
    2979           0 :   return 0;
    2980             : }
    2981             : 
    2982           0 : int Channel::SetExternalMixing(bool enabled) {
    2983             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    2984             :                "Channel::SetExternalMixing(enabled=%d)", enabled);
    2985             : 
    2986           0 :   if (channel_state_.Get().playing) {
    2987           0 :     _engineStatisticsPtr->SetLastError(
    2988             :         VE_INVALID_OPERATION, kTraceError,
    2989             :         "Channel::SetExternalMixing() "
    2990           0 :         "external mixing cannot be changed while playing.");
    2991           0 :     return -1;
    2992             :   }
    2993             : 
    2994           0 :   _externalMixing = enabled;
    2995             : 
    2996           0 :   return 0;
    2997             : }
    2998             : 
    2999           0 : int Channel::GetNetworkStatistics(NetworkStatistics& stats) {
    3000           0 :   return audio_coding_->GetNetworkStatistics(&stats);
    3001             : }
    3002             : 
    3003           0 : void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
    3004           0 :   audio_coding_->GetDecodingCallStatistics(stats);
    3005           0 : }
    3006             : 
    3007           0 : bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms,
    3008             :                                int* playout_buffer_delay_ms,
    3009             :                                int* avsync_offset_ms) const {
    3010           0 :   rtc::CritScope lock(&video_sync_lock_);
    3011           0 :   *jitter_buffer_delay_ms = audio_coding_->FilteredCurrentDelayMs();
    3012           0 :   *playout_buffer_delay_ms = playout_delay_ms_;
    3013           0 :   *avsync_offset_ms = _current_sync_offset;
    3014           0 :   return true;
    3015             : }
    3016             : 
    3017           0 : uint32_t Channel::GetDelayEstimate() const {
    3018           0 :   int jitter_buffer_delay_ms = 0;
    3019           0 :   int playout_buffer_delay_ms = 0;
    3020           0 :   int avsync_offset_ms = 0;
    3021           0 :   GetDelayEstimate(&jitter_buffer_delay_ms, &playout_buffer_delay_ms, &avsync_offset_ms);
    3022           0 :   return jitter_buffer_delay_ms + playout_buffer_delay_ms;
    3023             : }
    3024             : 
    3025           0 : int Channel::LeastRequiredDelayMs() const {
    3026           0 :   return audio_coding_->LeastRequiredDelayMs();
    3027             : }
    3028             : 
    3029           0 : int Channel::SetMinimumPlayoutDelay(int delayMs) {
    3030             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    3031             :                "Channel::SetMinimumPlayoutDelay()");
    3032           0 :   if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) ||
    3033             :       (delayMs > kVoiceEngineMaxMinPlayoutDelayMs)) {
    3034           0 :     _engineStatisticsPtr->SetLastError(
    3035             :         VE_INVALID_ARGUMENT, kTraceError,
    3036           0 :         "SetMinimumPlayoutDelay() invalid min delay");
    3037           0 :     return -1;
    3038             :   }
    3039           0 :   if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0) {
    3040           0 :     _engineStatisticsPtr->SetLastError(
    3041             :         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
    3042           0 :         "SetMinimumPlayoutDelay() failed to set min playout delay");
    3043           0 :     return -1;
    3044             :   }
    3045           0 :   return 0;
    3046             : }
    3047             : 
    3048           0 : int Channel::GetPlayoutTimestamp(unsigned int& timestamp) {
    3049           0 :   uint32_t playout_timestamp_rtp = 0;
    3050             :   {
    3051           0 :     rtc::CritScope lock(&video_sync_lock_);
    3052           0 :     playout_timestamp_rtp = playout_timestamp_rtp_;
    3053             :   }
    3054           0 :   if (playout_timestamp_rtp == 0) {
    3055           0 :     _engineStatisticsPtr->SetLastError(
    3056             :         VE_CANNOT_RETRIEVE_VALUE, kTraceStateInfo,
    3057           0 :         "GetPlayoutTimestamp() failed to retrieve timestamp");
    3058           0 :     return -1;
    3059             :   }
    3060           0 :   timestamp = playout_timestamp_rtp;
    3061           0 :   return 0;
    3062             : }
    3063             : 
    3064           0 : int Channel::SetInitTimestamp(unsigned int timestamp) {
    3065             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    3066             :                "Channel::SetInitTimestamp()");
    3067           0 :   if (channel_state_.Get().sending) {
    3068           0 :     _engineStatisticsPtr->SetLastError(VE_SENDING, kTraceError,
    3069           0 :                                        "SetInitTimestamp() already sending");
    3070           0 :     return -1;
    3071             :   }
    3072           0 :   _rtpRtcpModule->SetStartTimestamp(timestamp);
    3073           0 :   return 0;
    3074             : }
    3075             : 
    3076           0 : int Channel::SetInitSequenceNumber(short sequenceNumber) {
    3077             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    3078             :                "Channel::SetInitSequenceNumber()");
    3079           0 :   if (channel_state_.Get().sending) {
    3080           0 :     _engineStatisticsPtr->SetLastError(
    3081           0 :         VE_SENDING, kTraceError, "SetInitSequenceNumber() already sending");
    3082           0 :     return -1;
    3083             :   }
    3084           0 :   _rtpRtcpModule->SetSequenceNumber(sequenceNumber);
    3085           0 :   return 0;
    3086             : }
    3087             : 
    3088           0 : int Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule,
    3089             :                         RtpReceiver** rtp_receiver) const {
    3090           0 :   *rtpRtcpModule = _rtpRtcpModule.get();
    3091           0 :   *rtp_receiver = rtp_receiver_.get();
    3092           0 :   return 0;
    3093             : }
    3094             : 
    3095             : // TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use
    3096             : // a shared helper.
    3097           0 : int32_t Channel::MixOrReplaceAudioWithFile(int mixingFrequency) {
    3098           0 :   std::unique_ptr<int16_t[]> fileBuffer(new int16_t[640]);
    3099           0 :   size_t fileSamples(0);
    3100             : 
    3101             :   {
    3102           0 :     rtc::CritScope cs(&_fileCritSect);
    3103             : 
    3104           0 :     if (!input_file_player_) {
    3105             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3106             :                    "Channel::MixOrReplaceAudioWithFile() fileplayer"
    3107             :                    " doesnt exist");
    3108           0 :       return -1;
    3109             :     }
    3110             : 
    3111           0 :     if (input_file_player_->Get10msAudioFromFile(fileBuffer.get(), &fileSamples,
    3112           0 :                                                  mixingFrequency) == -1) {
    3113             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3114             :                    "Channel::MixOrReplaceAudioWithFile() file mixing "
    3115             :                    "failed");
    3116           0 :       return -1;
    3117             :     }
    3118           0 :     if (fileSamples == 0) {
    3119             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3120             :                    "Channel::MixOrReplaceAudioWithFile() file is ended");
    3121           0 :       return 0;
    3122             :     }
    3123             :   }
    3124             : 
    3125           0 :   assert(_audioFrame.samples_per_channel_ == fileSamples);
    3126             : 
    3127           0 :   if (_mixFileWithMicrophone) {
    3128             :     // Currently file stream is always mono.
    3129             :     // TODO(xians): Change the code when FilePlayer supports real stereo.
    3130           0 :     MixWithSat(_audioFrame.data_, _audioFrame.num_channels_, fileBuffer.get(),
    3131           0 :                1, fileSamples);
    3132             :   } else {
    3133             :     // Replace ACM audio with file.
    3134             :     // Currently file stream is always mono.
    3135             :     // TODO(xians): Change the code when FilePlayer supports real stereo.
    3136           0 :     _audioFrame.UpdateFrame(
    3137           0 :         _channelId, 0xFFFFFFFF, fileBuffer.get(), fileSamples, mixingFrequency,
    3138           0 :         AudioFrame::kNormalSpeech, AudioFrame::kVadUnknown, 1);
    3139             :   }
    3140           0 :   return 0;
    3141             : }
    3142             : 
    3143           0 : int32_t Channel::MixAudioWithFile(AudioFrame& audioFrame, int mixingFrequency) {
    3144           0 :   assert(mixingFrequency <= 48000);
    3145             : 
    3146           0 :   std::unique_ptr<int16_t[]> fileBuffer(new int16_t[960]);
    3147           0 :   size_t fileSamples(0);
    3148             : 
    3149             :   {
    3150           0 :     rtc::CritScope cs(&_fileCritSect);
    3151             : 
    3152           0 :     if (!output_file_player_) {
    3153             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3154             :                    "Channel::MixAudioWithFile() file mixing failed");
    3155           0 :       return -1;
    3156             :     }
    3157             : 
    3158             :     // We should get the frequency we ask for.
    3159           0 :     if (output_file_player_->Get10msAudioFromFile(
    3160           0 :             fileBuffer.get(), &fileSamples, mixingFrequency) == -1) {
    3161             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3162             :                    "Channel::MixAudioWithFile() file mixing failed");
    3163           0 :       return -1;
    3164             :     }
    3165             :   }
    3166             : 
    3167           0 :   if (audioFrame.samples_per_channel_ == fileSamples) {
    3168             :     // Currently file stream is always mono.
    3169             :     // TODO(xians): Change the code when FilePlayer supports real stereo.
    3170           0 :     MixWithSat(audioFrame.data_, audioFrame.num_channels_, fileBuffer.get(), 1,
    3171           0 :                fileSamples);
    3172             :   } else {
    3173             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3174             :                  "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS
    3175             :                  ") != "
    3176             :                  "fileSamples(%" PRIuS ")",
    3177             :                  audioFrame.samples_per_channel_, fileSamples);
    3178           0 :     return -1;
    3179             :   }
    3180             : 
    3181           0 :   return 0;
    3182             : }
    3183             : 
    3184           0 : void Channel::UpdatePlayoutTimestamp(bool rtcp) {
    3185           0 :   jitter_buffer_playout_timestamp_ = audio_coding_->PlayoutTimestamp();
    3186             : 
    3187           0 :   if (!jitter_buffer_playout_timestamp_) {
    3188             :     // This can happen if this channel has not received any RTP packets. In
    3189             :     // this case, NetEq is not capable of computing a playout timestamp.
    3190           0 :     return;
    3191             :   }
    3192             : 
    3193           0 :   uint16_t delay_ms = 0;
    3194           0 :   if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) {
    3195             :     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3196             :                  "Channel::UpdatePlayoutTimestamp() failed to read playout"
    3197             :                  " delay from the ADM");
    3198           0 :     _engineStatisticsPtr->SetLastError(
    3199             :         VE_CANNOT_RETRIEVE_VALUE, kTraceError,
    3200           0 :         "UpdatePlayoutTimestamp() failed to retrieve playout delay");
    3201           0 :     return;
    3202             :   }
    3203             : 
    3204           0 :   RTC_DCHECK(jitter_buffer_playout_timestamp_);
    3205           0 :   uint32_t playout_timestamp = *jitter_buffer_playout_timestamp_;
    3206             : 
    3207             :   // Remove the playout delay.
    3208           0 :   playout_timestamp -= (delay_ms * (GetRtpTimestampRateHz() / 1000));
    3209             : 
    3210             :   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId, _channelId),
    3211             :                "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu",
    3212             :                playout_timestamp);
    3213             : 
    3214             :   {
    3215           0 :     rtc::CritScope lock(&video_sync_lock_);
    3216           0 :     if (rtcp) {
    3217           0 :       playout_timestamp_rtcp_ = playout_timestamp;
    3218             :     } else {
    3219           0 :       playout_timestamp_rtp_ = playout_timestamp;
    3220             :     }
    3221           0 :     playout_delay_ms_ = delay_ms;
    3222             :   }
    3223             : }
    3224             : 
    3225           0 : void Channel::RegisterReceiveCodecsToRTPModule() {
    3226             :   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    3227             :                "Channel::RegisterReceiveCodecsToRTPModule()");
    3228             : 
    3229             :   CodecInst codec;
    3230           0 :   const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
    3231             : 
    3232           0 :   for (int idx = 0; idx < nSupportedCodecs; idx++) {
    3233             :     // Open up the RTP/RTCP receiver for all supported codecs
    3234           0 :     if ((audio_coding_->Codec(idx, &codec) == -1) ||
    3235           0 :         (rtp_receiver_->RegisterReceivePayload(codec) == -1)) {
    3236             :       WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId, _channelId),
    3237             :                    "Channel::RegisterReceiveCodecsToRTPModule() unable"
    3238             :                    " to register %s (%d/%d/%" PRIuS
    3239             :                    "/%d) to RTP/RTCP "
    3240             :                    "receiver",
    3241             :                    codec.plname, codec.pltype, codec.plfreq, codec.channels,
    3242             :                    codec.rate);
    3243             :     } else {
    3244             :       WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    3245             :                    "Channel::RegisterReceiveCodecsToRTPModule() %s "
    3246             :                    "(%d/%d/%" PRIuS
    3247             :                    "/%d) has been added to the RTP/RTCP "
    3248             :                    "receiver",
    3249             :                    codec.plname, codec.pltype, codec.plfreq, codec.channels,
    3250             :                    codec.rate);
    3251             :     }
    3252             :   }
    3253           0 : }
    3254             : 
    3255           0 : int Channel::SetSendRtpHeaderExtension(bool enable,
    3256             :                                        RTPExtensionType type,
    3257             :                                        unsigned char id) {
    3258           0 :   int error = 0;
    3259           0 :   _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type);
    3260           0 :   if (enable) {
    3261           0 :     error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(type, id);
    3262             :   }
    3263           0 :   return error;
    3264             : }
    3265             : 
    3266           0 : int Channel::GetRtpTimestampRateHz() const {
    3267           0 :   const auto format = audio_coding_->ReceiveFormat();
    3268             :   // Default to the playout frequency if we've not gotten any packets yet.
    3269             :   // TODO(ossu): Zero clockrate can only happen if we've added an external
    3270             :   // decoder for a format we don't support internally. Remove once that way of
    3271             :   // adding decoders is gone!
    3272           0 :   return (format && format->clockrate_hz != 0)
    3273           0 :              ? format->clockrate_hz
    3274           0 :              : audio_coding_->PlayoutFrequency();
    3275             : }
    3276             : 
    3277           0 : int64_t Channel::GetRTT(bool allow_associate_channel) const {
    3278           0 :   RtcpMode method = _rtpRtcpModule->RTCP();
    3279           0 :   if (method == RtcpMode::kOff) {
    3280           0 :     return 0;
    3281             :   }
    3282           0 :   std::vector<RTCPReportBlock> report_blocks;
    3283           0 :   _rtpRtcpModule->RemoteRTCPStat(&report_blocks);
    3284             : 
    3285           0 :   int64_t rtt = 0;
    3286           0 :   if (report_blocks.empty()) {
    3287           0 :     if (allow_associate_channel) {
    3288           0 :       rtc::CritScope lock(&assoc_send_channel_lock_);
    3289           0 :       Channel* channel = associate_send_channel_.channel();
    3290             :       // Tries to get RTT from an associated channel. This is important for
    3291             :       // receive-only channels.
    3292           0 :       if (channel) {
    3293             :         // To prevent infinite recursion and deadlock, calling GetRTT of
    3294             :         // associate channel should always use "false" for argument:
    3295             :         // |allow_associate_channel|.
    3296           0 :         rtt = channel->GetRTT(false);
    3297             :       }
    3298             :     }
    3299           0 :     return rtt;
    3300             :   }
    3301             : 
    3302           0 :   uint32_t remoteSSRC = rtp_receiver_->SSRC();
    3303           0 :   std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
    3304           0 :   for (; it != report_blocks.end(); ++it) {
    3305           0 :     if (it->remoteSSRC == remoteSSRC)
    3306           0 :       break;
    3307             :   }
    3308           0 :   if (it == report_blocks.end()) {
    3309             :     // We have not received packets with SSRC matching the report blocks.
    3310             :     // To calculate RTT we try with the SSRC of the first report block.
    3311             :     // This is very important for send-only channels where we don't know
    3312             :     // the SSRC of the other end.
    3313           0 :     remoteSSRC = report_blocks[0].remoteSSRC;
    3314             :   }
    3315             : 
    3316           0 :   int64_t avg_rtt = 0;
    3317           0 :   int64_t max_rtt = 0;
    3318           0 :   int64_t min_rtt = 0;
    3319           0 :   if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) !=
    3320             :       0) {
    3321           0 :     return 0;
    3322             :   }
    3323           0 :   return rtt;
    3324             : }
    3325             : 
    3326             : }  // namespace voe
    3327             : }  // namespace webrtc

Generated by: LCOV version 1.13