Home | History | Annotate | Download | only in voice_engine
      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/base/checks.h"
     17 #include "webrtc/base/format_macros.h"
     18 #include "webrtc/base/logging.h"
     19 #include "webrtc/base/thread_checker.h"
     20 #include "webrtc/base/timeutils.h"
     21 #include "webrtc/common.h"
     22 #include "webrtc/config.h"
     23 #include "webrtc/modules/audio_device/include/audio_device.h"
     24 #include "webrtc/modules/audio_processing/include/audio_processing.h"
     25 #include "webrtc/modules/include/module_common_types.h"
     26 #include "webrtc/modules/pacing/packet_router.h"
     27 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
     28 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
     29 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
     30 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
     31 #include "webrtc/modules/utility/include/audio_frame_operations.h"
     32 #include "webrtc/modules/utility/include/process_thread.h"
     33 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
     34 #include "webrtc/system_wrappers/include/trace.h"
     35 #include "webrtc/voice_engine/include/voe_base.h"
     36 #include "webrtc/voice_engine/include/voe_external_media.h"
     37 #include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
     38 #include "webrtc/voice_engine/output_mixer.h"
     39 #include "webrtc/voice_engine/statistics.h"
     40 #include "webrtc/voice_engine/transmit_mixer.h"
     41 #include "webrtc/voice_engine/utility.h"
     42 
     43 #if defined(_WIN32)
     44 #include <Qos.h>
     45 #endif
     46 
     47 namespace webrtc {
     48 namespace voe {
     49 
     50 class TransportFeedbackProxy : public TransportFeedbackObserver {
     51  public:
     52   TransportFeedbackProxy() : feedback_observer_(nullptr) {
     53     pacer_thread_.DetachFromThread();
     54     network_thread_.DetachFromThread();
     55   }
     56 
     57   void SetTransportFeedbackObserver(
     58       TransportFeedbackObserver* feedback_observer) {
     59     RTC_DCHECK(thread_checker_.CalledOnValidThread());
     60     rtc::CritScope lock(&crit_);
     61     feedback_observer_ = feedback_observer;
     62   }
     63 
     64   // Implements TransportFeedbackObserver.
     65   void AddPacket(uint16_t sequence_number,
     66                  size_t length,
     67                  bool was_paced) override {
     68     RTC_DCHECK(pacer_thread_.CalledOnValidThread());
     69     rtc::CritScope lock(&crit_);
     70     if (feedback_observer_)
     71       feedback_observer_->AddPacket(sequence_number, length, was_paced);
     72   }
     73   void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override {
     74     RTC_DCHECK(network_thread_.CalledOnValidThread());
     75     rtc::CritScope lock(&crit_);
     76     if (feedback_observer_)
     77       feedback_observer_->OnTransportFeedback(feedback);
     78   }
     79 
     80  private:
     81   rtc::CriticalSection crit_;
     82   rtc::ThreadChecker thread_checker_;
     83   rtc::ThreadChecker pacer_thread_;
     84   rtc::ThreadChecker network_thread_;
     85   TransportFeedbackObserver* feedback_observer_ GUARDED_BY(&crit_);
     86 };
     87 
     88 class TransportSequenceNumberProxy : public TransportSequenceNumberAllocator {
     89  public:
     90   TransportSequenceNumberProxy() : seq_num_allocator_(nullptr) {
     91     pacer_thread_.DetachFromThread();
     92   }
     93 
     94   void SetSequenceNumberAllocator(
     95       TransportSequenceNumberAllocator* seq_num_allocator) {
     96     RTC_DCHECK(thread_checker_.CalledOnValidThread());
     97     rtc::CritScope lock(&crit_);
     98     seq_num_allocator_ = seq_num_allocator;
     99   }
    100 
    101   // Implements TransportSequenceNumberAllocator.
    102   uint16_t AllocateSequenceNumber() override {
    103     RTC_DCHECK(pacer_thread_.CalledOnValidThread());
    104     rtc::CritScope lock(&crit_);
    105     if (!seq_num_allocator_)
    106       return 0;
    107     return seq_num_allocator_->AllocateSequenceNumber();
    108   }
    109 
    110  private:
    111   rtc::CriticalSection crit_;
    112   rtc::ThreadChecker thread_checker_;
    113   rtc::ThreadChecker pacer_thread_;
    114   TransportSequenceNumberAllocator* seq_num_allocator_ GUARDED_BY(&crit_);
    115 };
    116 
    117 class RtpPacketSenderProxy : public RtpPacketSender {
    118  public:
    119   RtpPacketSenderProxy() : rtp_packet_sender_(nullptr) {
    120   }
    121 
    122   void SetPacketSender(RtpPacketSender* rtp_packet_sender) {
    123     RTC_DCHECK(thread_checker_.CalledOnValidThread());
    124     rtc::CritScope lock(&crit_);
    125     rtp_packet_sender_ = rtp_packet_sender;
    126   }
    127 
    128   // Implements RtpPacketSender.
    129   void InsertPacket(Priority priority,
    130                     uint32_t ssrc,
    131                     uint16_t sequence_number,
    132                     int64_t capture_time_ms,
    133                     size_t bytes,
    134                     bool retransmission) override {
    135     rtc::CritScope lock(&crit_);
    136     if (rtp_packet_sender_) {
    137       rtp_packet_sender_->InsertPacket(priority, ssrc, sequence_number,
    138                                        capture_time_ms, bytes, retransmission);
    139     }
    140   }
    141 
    142  private:
    143   rtc::ThreadChecker thread_checker_;
    144   rtc::CriticalSection crit_;
    145   RtpPacketSender* rtp_packet_sender_ GUARDED_BY(&crit_);
    146 };
    147 
    148 // Extend the default RTCP statistics struct with max_jitter, defined as the
    149 // maximum jitter value seen in an RTCP report block.
    150 struct ChannelStatistics : public RtcpStatistics {
    151   ChannelStatistics() : rtcp(), max_jitter(0) {}
    152 
    153   RtcpStatistics rtcp;
    154   uint32_t max_jitter;
    155 };
    156 
    157 // Statistics callback, called at each generation of a new RTCP report block.
    158 class StatisticsProxy : public RtcpStatisticsCallback {
    159  public:
    160   StatisticsProxy(uint32_t ssrc)
    161    : stats_lock_(CriticalSectionWrapper::CreateCriticalSection()),
    162      ssrc_(ssrc) {}
    163   virtual ~StatisticsProxy() {}
    164 
    165   void StatisticsUpdated(const RtcpStatistics& statistics,
    166                          uint32_t ssrc) override {
    167     if (ssrc != ssrc_)
    168       return;
    169 
    170     CriticalSectionScoped cs(stats_lock_.get());
    171     stats_.rtcp = statistics;
    172     if (statistics.jitter > stats_.max_jitter) {
    173       stats_.max_jitter = statistics.jitter;
    174     }
    175   }
    176 
    177   void CNameChanged(const char* cname, uint32_t ssrc) override {}
    178 
    179   ChannelStatistics GetStats() {
    180     CriticalSectionScoped cs(stats_lock_.get());
    181     return stats_;
    182   }
    183 
    184  private:
    185   // StatisticsUpdated calls are triggered from threads in the RTP module,
    186   // while GetStats calls can be triggered from the public voice engine API,
    187   // hence synchronization is needed.
    188   rtc::scoped_ptr<CriticalSectionWrapper> stats_lock_;
    189   const uint32_t ssrc_;
    190   ChannelStatistics stats_;
    191 };
    192 
    193 class VoERtcpObserver : public RtcpBandwidthObserver {
    194  public:
    195   explicit VoERtcpObserver(Channel* owner) : owner_(owner) {}
    196   virtual ~VoERtcpObserver() {}
    197 
    198   void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
    199     // Not used for Voice Engine.
    200   }
    201 
    202   void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
    203                                     int64_t rtt,
    204                                     int64_t now_ms) override {
    205     // TODO(mflodman): Do we need to aggregate reports here or can we jut send
    206     // what we get? I.e. do we ever get multiple reports bundled into one RTCP
    207     // report for VoiceEngine?
    208     if (report_blocks.empty())
    209       return;
    210 
    211     int fraction_lost_aggregate = 0;
    212     int total_number_of_packets = 0;
    213 
    214     // If receiving multiple report blocks, calculate the weighted average based
    215     // on the number of packets a report refers to.
    216     for (ReportBlockList::const_iterator block_it = report_blocks.begin();
    217          block_it != report_blocks.end(); ++block_it) {
    218       // Find the previous extended high sequence number for this remote SSRC,
    219       // to calculate the number of RTP packets this report refers to. Ignore if
    220       // we haven't seen this SSRC before.
    221       std::map<uint32_t, uint32_t>::iterator seq_num_it =
    222           extended_max_sequence_number_.find(block_it->sourceSSRC);
    223       int number_of_packets = 0;
    224       if (seq_num_it != extended_max_sequence_number_.end()) {
    225         number_of_packets = block_it->extendedHighSeqNum - seq_num_it->second;
    226       }
    227       fraction_lost_aggregate += number_of_packets * block_it->fractionLost;
    228       total_number_of_packets += number_of_packets;
    229 
    230       extended_max_sequence_number_[block_it->sourceSSRC] =
    231           block_it->extendedHighSeqNum;
    232     }
    233     int weighted_fraction_lost = 0;
    234     if (total_number_of_packets > 0) {
    235       weighted_fraction_lost = (fraction_lost_aggregate +
    236           total_number_of_packets / 2) / total_number_of_packets;
    237     }
    238     owner_->OnIncomingFractionLoss(weighted_fraction_lost);
    239   }
    240 
    241  private:
    242   Channel* owner_;
    243   // Maps remote side ssrc to extended highest sequence number received.
    244   std::map<uint32_t, uint32_t> extended_max_sequence_number_;
    245 };
    246 
    247 int32_t
    248 Channel::SendData(FrameType frameType,
    249                   uint8_t   payloadType,
    250                   uint32_t  timeStamp,
    251                   const uint8_t*  payloadData,
    252                   size_t    payloadSize,
    253                   const RTPFragmentationHeader* fragmentation)
    254 {
    255     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    256                  "Channel::SendData(frameType=%u, payloadType=%u, timeStamp=%u,"
    257                  " payloadSize=%" PRIuS ", fragmentation=0x%x)",
    258                  frameType, payloadType, timeStamp,
    259                  payloadSize, fragmentation);
    260 
    261     if (_includeAudioLevelIndication)
    262     {
    263         // Store current audio level in the RTP/RTCP module.
    264         // The level will be used in combination with voice-activity state
    265         // (frameType) to add an RTP header extension
    266         _rtpRtcpModule->SetAudioLevel(rms_level_.RMS());
    267     }
    268 
    269     // Push data from ACM to RTP/RTCP-module to deliver audio frame for
    270     // packetization.
    271     // This call will trigger Transport::SendPacket() from the RTP/RTCP module.
    272     if (_rtpRtcpModule->SendOutgoingData((FrameType&)frameType,
    273                                         payloadType,
    274                                         timeStamp,
    275                                         // Leaving the time when this frame was
    276                                         // received from the capture device as
    277                                         // undefined for voice for now.
    278                                         -1,
    279                                         payloadData,
    280                                         payloadSize,
    281                                         fragmentation) == -1)
    282     {
    283         _engineStatisticsPtr->SetLastError(
    284             VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
    285             "Channel::SendData() failed to send data to RTP/RTCP module");
    286         return -1;
    287     }
    288 
    289     _lastLocalTimeStamp = timeStamp;
    290     _lastPayloadType = payloadType;
    291 
    292     return 0;
    293 }
    294 
    295 int32_t
    296 Channel::InFrameType(FrameType frame_type)
    297 {
    298     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
    299                  "Channel::InFrameType(frame_type=%d)", frame_type);
    300 
    301     CriticalSectionScoped cs(&_callbackCritSect);
    302     _sendFrameType = (frame_type == kAudioFrameSpeech);
    303     return 0;
    304 }
    305 
    306 int32_t
    307 Channel::OnRxVadDetected(int vadDecision)
    308 {
    309     CriticalSectionScoped cs(&_callbackCritSect);
    310     if (_rxVadObserverPtr)
    311     {
    312         _rxVadObserverPtr->OnRxVad(_channelId, vadDecision);
    313     }
    314 
    315     return 0;
    316 }
    317 
    318 bool Channel::SendRtp(const uint8_t* data,
    319                       size_t len,
    320                       const PacketOptions& options) {
    321     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    322                  "Channel::SendPacket(channel=%d, len=%" PRIuS ")", len);
    323 
    324     CriticalSectionScoped cs(&_callbackCritSect);
    325 
    326     if (_transportPtr == NULL)
    327     {
    328         WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
    329                      "Channel::SendPacket() failed to send RTP packet due to"
    330                      " invalid transport object");
    331         return false;
    332     }
    333 
    334     uint8_t* bufferToSendPtr = (uint8_t*)data;
    335     size_t bufferLength = len;
    336 
    337     if (!_transportPtr->SendRtp(bufferToSendPtr, bufferLength, options)) {
    338       std::string transport_name =
    339           _externalTransport ? "external transport" : "WebRtc sockets";
    340       WEBRTC_TRACE(kTraceError, kTraceVoice,
    341                    VoEId(_instanceId,_channelId),
    342                    "Channel::SendPacket() RTP transmission using %s failed",
    343                    transport_name.c_str());
    344       return false;
    345     }
    346     return true;
    347 }
    348 
    349 bool
    350 Channel::SendRtcp(const uint8_t *data, size_t len)
    351 {
    352     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    353                  "Channel::SendRtcp(len=%" PRIuS ")", len);
    354 
    355     CriticalSectionScoped cs(&_callbackCritSect);
    356     if (_transportPtr == NULL)
    357     {
    358         WEBRTC_TRACE(kTraceError, kTraceVoice,
    359                      VoEId(_instanceId,_channelId),
    360                      "Channel::SendRtcp() failed to send RTCP packet"
    361                      " due to invalid transport object");
    362         return false;
    363     }
    364 
    365     uint8_t* bufferToSendPtr = (uint8_t*)data;
    366     size_t bufferLength = len;
    367 
    368     int n = _transportPtr->SendRtcp(bufferToSendPtr, bufferLength);
    369     if (n < 0) {
    370       std::string transport_name =
    371           _externalTransport ? "external transport" : "WebRtc sockets";
    372       WEBRTC_TRACE(kTraceInfo, kTraceVoice,
    373                    VoEId(_instanceId,_channelId),
    374                    "Channel::SendRtcp() transmission using %s failed",
    375                    transport_name.c_str());
    376       return false;
    377     }
    378     return true;
    379 }
    380 
    381 void Channel::OnPlayTelephoneEvent(uint8_t event,
    382                                    uint16_t lengthMs,
    383                                    uint8_t volume) {
    384     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    385                  "Channel::OnPlayTelephoneEvent(event=%u, lengthMs=%u,"
    386                  " volume=%u)", event, lengthMs, volume);
    387 
    388     if (!_playOutbandDtmfEvent || (event > 15))
    389     {
    390         // Ignore callback since feedback is disabled or event is not a
    391         // Dtmf tone event.
    392         return;
    393     }
    394 
    395     assert(_outputMixerPtr != NULL);
    396 
    397     // Start playing out the Dtmf tone (if playout is enabled).
    398     // Reduce length of tone with 80ms to the reduce risk of echo.
    399     _outputMixerPtr->PlayDtmfTone(event, lengthMs - 80, volume);
    400 }
    401 
    402 void
    403 Channel::OnIncomingSSRCChanged(uint32_t ssrc)
    404 {
    405     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
    406                  "Channel::OnIncomingSSRCChanged(SSRC=%d)", ssrc);
    407 
    408     // Update ssrc so that NTP for AV sync can be updated.
    409     _rtpRtcpModule->SetRemoteSSRC(ssrc);
    410 }
    411 
    412 void Channel::OnIncomingCSRCChanged(uint32_t CSRC, bool added) {
    413   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
    414                "Channel::OnIncomingCSRCChanged(CSRC=%d, added=%d)", CSRC,
    415                added);
    416 }
    417 
    418 int32_t Channel::OnInitializeDecoder(
    419     int8_t payloadType,
    420     const char payloadName[RTP_PAYLOAD_NAME_SIZE],
    421     int frequency,
    422     size_t channels,
    423     uint32_t rate) {
    424     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
    425                  "Channel::OnInitializeDecoder(payloadType=%d, "
    426                  "payloadName=%s, frequency=%u, channels=%" PRIuS ", rate=%u)",
    427                  payloadType, payloadName, frequency, channels, rate);
    428 
    429     CodecInst receiveCodec = {0};
    430     CodecInst dummyCodec = {0};
    431 
    432     receiveCodec.pltype = payloadType;
    433     receiveCodec.plfreq = frequency;
    434     receiveCodec.channels = channels;
    435     receiveCodec.rate = rate;
    436     strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
    437 
    438     audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels);
    439     receiveCodec.pacsize = dummyCodec.pacsize;
    440 
    441     // Register the new codec to the ACM
    442     if (audio_coding_->RegisterReceiveCodec(receiveCodec) == -1)
    443     {
    444         WEBRTC_TRACE(kTraceWarning, kTraceVoice,
    445                      VoEId(_instanceId, _channelId),
    446                      "Channel::OnInitializeDecoder() invalid codec ("
    447                      "pt=%d, name=%s) received - 1", payloadType, payloadName);
    448         _engineStatisticsPtr->SetLastError(VE_AUDIO_CODING_MODULE_ERROR);
    449         return -1;
    450     }
    451 
    452     return 0;
    453 }
    454 
    455 int32_t
    456 Channel::OnReceivedPayloadData(const uint8_t* payloadData,
    457                                size_t payloadSize,
    458                                const WebRtcRTPHeader* rtpHeader)
    459 {
    460     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    461                  "Channel::OnReceivedPayloadData(payloadSize=%" PRIuS ","
    462                  " payloadType=%u, audioChannel=%" PRIuS ")",
    463                  payloadSize,
    464                  rtpHeader->header.payloadType,
    465                  rtpHeader->type.Audio.channel);
    466 
    467     if (!channel_state_.Get().playing)
    468     {
    469         // Avoid inserting into NetEQ when we are not playing. Count the
    470         // packet as discarded.
    471         WEBRTC_TRACE(kTraceStream, kTraceVoice,
    472                      VoEId(_instanceId, _channelId),
    473                      "received packet is discarded since playing is not"
    474                      " activated");
    475         _numberOfDiscardedPackets++;
    476         return 0;
    477     }
    478 
    479     // Push the incoming payload (parsed and ready for decoding) into the ACM
    480     if (audio_coding_->IncomingPacket(payloadData,
    481                                       payloadSize,
    482                                       *rtpHeader) != 0)
    483     {
    484         _engineStatisticsPtr->SetLastError(
    485             VE_AUDIO_CODING_MODULE_ERROR, kTraceWarning,
    486             "Channel::OnReceivedPayloadData() unable to push data to the ACM");
    487         return -1;
    488     }
    489 
    490     // Update the packet delay.
    491     UpdatePacketDelay(rtpHeader->header.timestamp,
    492                       rtpHeader->header.sequenceNumber);
    493 
    494     int64_t round_trip_time = 0;
    495     _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time,
    496                         NULL, NULL, NULL);
    497 
    498     std::vector<uint16_t> nack_list = audio_coding_->GetNackList(
    499         round_trip_time);
    500     if (!nack_list.empty()) {
    501       // Can't use nack_list.data() since it's not supported by all
    502       // compilers.
    503       ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size()));
    504     }
    505     return 0;
    506 }
    507 
    508 bool Channel::OnRecoveredPacket(const uint8_t* rtp_packet,
    509                                 size_t rtp_packet_length) {
    510   RTPHeader header;
    511   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
    512     WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVoice, _channelId,
    513                  "IncomingPacket invalid RTP header");
    514     return false;
    515   }
    516   header.payload_type_frequency =
    517       rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
    518   if (header.payload_type_frequency < 0)
    519     return false;
    520   return ReceivePacket(rtp_packet, rtp_packet_length, header, false);
    521 }
    522 
    523 int32_t Channel::GetAudioFrame(int32_t id, AudioFrame* audioFrame)
    524 {
    525     if (event_log_) {
    526       unsigned int ssrc;
    527       RTC_CHECK_EQ(GetLocalSSRC(ssrc), 0);
    528       event_log_->LogAudioPlayout(ssrc);
    529     }
    530     // Get 10ms raw PCM data from the ACM (mixer limits output frequency)
    531     if (audio_coding_->PlayoutData10Ms(audioFrame->sample_rate_hz_,
    532                                        audioFrame) == -1)
    533     {
    534         WEBRTC_TRACE(kTraceError, kTraceVoice,
    535                      VoEId(_instanceId,_channelId),
    536                      "Channel::GetAudioFrame() PlayoutData10Ms() failed!");
    537         // In all likelihood, the audio in this frame is garbage. We return an
    538         // error so that the audio mixer module doesn't add it to the mix. As
    539         // a result, it won't be played out and the actions skipped here are
    540         // irrelevant.
    541         return -1;
    542     }
    543 
    544     if (_RxVadDetection)
    545     {
    546         UpdateRxVadDetection(*audioFrame);
    547     }
    548 
    549     // Convert module ID to internal VoE channel ID
    550     audioFrame->id_ = VoEChannelId(audioFrame->id_);
    551     // Store speech type for dead-or-alive detection
    552     _outputSpeechType = audioFrame->speech_type_;
    553 
    554     ChannelState::State state = channel_state_.Get();
    555 
    556     if (state.rx_apm_is_enabled) {
    557       int err = rx_audioproc_->ProcessStream(audioFrame);
    558       if (err) {
    559         LOG(LS_ERROR) << "ProcessStream() error: " << err;
    560         assert(false);
    561       }
    562     }
    563 
    564     {
    565       // Pass the audio buffers to an optional sink callback, before applying
    566       // scaling/panning, as that applies to the mix operation.
    567       // External recipients of the audio (e.g. via AudioTrack), will do their
    568       // own mixing/dynamic processing.
    569       CriticalSectionScoped cs(&_callbackCritSect);
    570       if (audio_sink_) {
    571         AudioSinkInterface::Data data(
    572             &audioFrame->data_[0],
    573             audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_,
    574             audioFrame->num_channels_, audioFrame->timestamp_);
    575         audio_sink_->OnData(data);
    576       }
    577     }
    578 
    579     float output_gain = 1.0f;
    580     float left_pan =  1.0f;
    581     float right_pan =  1.0f;
    582     {
    583       CriticalSectionScoped cs(&volume_settings_critsect_);
    584       output_gain = _outputGain;
    585       left_pan = _panLeft;
    586       right_pan= _panRight;
    587     }
    588 
    589     // Output volume scaling
    590     if (output_gain < 0.99f || output_gain > 1.01f)
    591     {
    592         AudioFrameOperations::ScaleWithSat(output_gain, *audioFrame);
    593     }
    594 
    595     // Scale left and/or right channel(s) if stereo and master balance is
    596     // active
    597 
    598     if (left_pan != 1.0f || right_pan != 1.0f)
    599     {
    600         if (audioFrame->num_channels_ == 1)
    601         {
    602             // Emulate stereo mode since panning is active.
    603             // The mono signal is copied to both left and right channels here.
    604             AudioFrameOperations::MonoToStereo(audioFrame);
    605         }
    606         // For true stereo mode (when we are receiving a stereo signal), no
    607         // action is needed.
    608 
    609         // Do the panning operation (the audio frame contains stereo at this
    610         // stage)
    611         AudioFrameOperations::Scale(left_pan, right_pan, *audioFrame);
    612     }
    613 
    614     // Mix decoded PCM output with file if file mixing is enabled
    615     if (state.output_file_playing)
    616     {
    617         MixAudioWithFile(*audioFrame, audioFrame->sample_rate_hz_);
    618     }
    619 
    620     // External media
    621     if (_outputExternalMedia)
    622     {
    623         CriticalSectionScoped cs(&_callbackCritSect);
    624         const bool isStereo = (audioFrame->num_channels_ == 2);
    625         if (_outputExternalMediaCallbackPtr)
    626         {
    627           _outputExternalMediaCallbackPtr->Process(
    628               _channelId, kPlaybackPerChannel, (int16_t*)audioFrame->data_,
    629               audioFrame->samples_per_channel_, audioFrame->sample_rate_hz_,
    630               isStereo);
    631         }
    632     }
    633 
    634     // Record playout if enabled
    635     {
    636         CriticalSectionScoped cs(&_fileCritSect);
    637 
    638         if (_outputFileRecording && _outputFileRecorderPtr)
    639         {
    640             _outputFileRecorderPtr->RecordAudioToFile(*audioFrame);
    641         }
    642     }
    643 
    644     // Measure audio level (0-9)
    645     _outputAudioLevel.ComputeLevel(*audioFrame);
    646 
    647     if (capture_start_rtp_time_stamp_ < 0 && audioFrame->timestamp_ != 0) {
    648       // The first frame with a valid rtp timestamp.
    649       capture_start_rtp_time_stamp_ = audioFrame->timestamp_;
    650     }
    651 
    652     if (capture_start_rtp_time_stamp_ >= 0) {
    653       // audioFrame.timestamp_ should be valid from now on.
    654 
    655       // Compute elapsed time.
    656       int64_t unwrap_timestamp =
    657           rtp_ts_wraparound_handler_->Unwrap(audioFrame->timestamp_);
    658       audioFrame->elapsed_time_ms_ =
    659           (unwrap_timestamp - capture_start_rtp_time_stamp_) /
    660           (GetPlayoutFrequency() / 1000);
    661 
    662       {
    663         CriticalSectionScoped lock(ts_stats_lock_.get());
    664         // Compute ntp time.
    665         audioFrame->ntp_time_ms_ = ntp_estimator_.Estimate(
    666             audioFrame->timestamp_);
    667         // |ntp_time_ms_| won't be valid until at least 2 RTCP SRs are received.
    668         if (audioFrame->ntp_time_ms_ > 0) {
    669           // Compute |capture_start_ntp_time_ms_| so that
    670           // |capture_start_ntp_time_ms_| + |elapsed_time_ms_| == |ntp_time_ms_|
    671           capture_start_ntp_time_ms_ =
    672               audioFrame->ntp_time_ms_ - audioFrame->elapsed_time_ms_;
    673         }
    674       }
    675     }
    676 
    677     return 0;
    678 }
    679 
    680 int32_t
    681 Channel::NeededFrequency(int32_t id) const
    682 {
    683     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    684                  "Channel::NeededFrequency(id=%d)", id);
    685 
    686     int highestNeeded = 0;
    687 
    688     // Determine highest needed receive frequency
    689     int32_t receiveFrequency = audio_coding_->ReceiveFrequency();
    690 
    691     // Return the bigger of playout and receive frequency in the ACM.
    692     if (audio_coding_->PlayoutFrequency() > receiveFrequency)
    693     {
    694         highestNeeded = audio_coding_->PlayoutFrequency();
    695     }
    696     else
    697     {
    698         highestNeeded = receiveFrequency;
    699     }
    700 
    701     // Special case, if we're playing a file on the playout side
    702     // we take that frequency into consideration as well
    703     // This is not needed on sending side, since the codec will
    704     // limit the spectrum anyway.
    705     if (channel_state_.Get().output_file_playing)
    706     {
    707         CriticalSectionScoped cs(&_fileCritSect);
    708         if (_outputFilePlayerPtr)
    709         {
    710             if(_outputFilePlayerPtr->Frequency()>highestNeeded)
    711             {
    712                 highestNeeded=_outputFilePlayerPtr->Frequency();
    713             }
    714         }
    715     }
    716 
    717     return(highestNeeded);
    718 }
    719 
    720 int32_t Channel::CreateChannel(Channel*& channel,
    721                                int32_t channelId,
    722                                uint32_t instanceId,
    723                                RtcEventLog* const event_log,
    724                                const Config& config) {
    725     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId),
    726                  "Channel::CreateChannel(channelId=%d, instanceId=%d)",
    727         channelId, instanceId);
    728 
    729     channel = new Channel(channelId, instanceId, event_log, config);
    730     if (channel == NULL)
    731     {
    732         WEBRTC_TRACE(kTraceMemory, kTraceVoice,
    733                      VoEId(instanceId,channelId),
    734                      "Channel::CreateChannel() unable to allocate memory for"
    735                      " channel");
    736         return -1;
    737     }
    738     return 0;
    739 }
    740 
    741 void
    742 Channel::PlayNotification(int32_t id, uint32_t durationMs)
    743 {
    744     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    745                  "Channel::PlayNotification(id=%d, durationMs=%d)",
    746                  id, durationMs);
    747 
    748     // Not implement yet
    749 }
    750 
    751 void
    752 Channel::RecordNotification(int32_t id, uint32_t durationMs)
    753 {
    754     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    755                  "Channel::RecordNotification(id=%d, durationMs=%d)",
    756                  id, durationMs);
    757 
    758     // Not implement yet
    759 }
    760 
    761 void
    762 Channel::PlayFileEnded(int32_t id)
    763 {
    764     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    765                  "Channel::PlayFileEnded(id=%d)", id);
    766 
    767     if (id == _inputFilePlayerId)
    768     {
    769         channel_state_.SetInputFilePlaying(false);
    770         WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
    771                      VoEId(_instanceId,_channelId),
    772                      "Channel::PlayFileEnded() => input file player module is"
    773                      " shutdown");
    774     }
    775     else if (id == _outputFilePlayerId)
    776     {
    777         channel_state_.SetOutputFilePlaying(false);
    778         WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
    779                      VoEId(_instanceId,_channelId),
    780                      "Channel::PlayFileEnded() => output file player module is"
    781                      " shutdown");
    782     }
    783 }
    784 
    785 void
    786 Channel::RecordFileEnded(int32_t id)
    787 {
    788     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
    789                  "Channel::RecordFileEnded(id=%d)", id);
    790 
    791     assert(id == _outputFileRecorderId);
    792 
    793     CriticalSectionScoped cs(&_fileCritSect);
    794 
    795     _outputFileRecording = false;
    796     WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
    797                  VoEId(_instanceId,_channelId),
    798                  "Channel::RecordFileEnded() => output file recorder module is"
    799                  " shutdown");
    800 }
    801 
    802 Channel::Channel(int32_t channelId,
    803                  uint32_t instanceId,
    804                  RtcEventLog* const event_log,
    805                  const Config& config)
    806     : _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
    807       _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
    808       volume_settings_critsect_(
    809           *CriticalSectionWrapper::CreateCriticalSection()),
    810       _instanceId(instanceId),
    811       _channelId(channelId),
    812       event_log_(event_log),
    813       rtp_header_parser_(RtpHeaderParser::Create()),
    814       rtp_payload_registry_(
    815           new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true))),
    816       rtp_receive_statistics_(
    817           ReceiveStatistics::Create(Clock::GetRealTimeClock())),
    818       rtp_receiver_(
    819           RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(),
    820                                            this,
    821                                            this,
    822                                            this,
    823                                            rtp_payload_registry_.get())),
    824       telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()),
    825       _outputAudioLevel(),
    826       _externalTransport(false),
    827       _inputFilePlayerPtr(NULL),
    828       _outputFilePlayerPtr(NULL),
    829       _outputFileRecorderPtr(NULL),
    830       // Avoid conflict with other channels by adding 1024 - 1026,
    831       // won't use as much as 1024 channels.
    832       _inputFilePlayerId(VoEModuleId(instanceId, channelId) + 1024),
    833       _outputFilePlayerId(VoEModuleId(instanceId, channelId) + 1025),
    834       _outputFileRecorderId(VoEModuleId(instanceId, channelId) + 1026),
    835       _outputFileRecording(false),
    836       _inbandDtmfQueue(VoEModuleId(instanceId, channelId)),
    837       _inbandDtmfGenerator(VoEModuleId(instanceId, channelId)),
    838       _outputExternalMedia(false),
    839       _inputExternalMediaCallbackPtr(NULL),
    840       _outputExternalMediaCallbackPtr(NULL),
    841       _timeStamp(0),  // This is just an offset, RTP module will add it's own
    842                       // random offset
    843       _sendTelephoneEventPayloadType(106),
    844       ntp_estimator_(Clock::GetRealTimeClock()),
    845       jitter_buffer_playout_timestamp_(0),
    846       playout_timestamp_rtp_(0),
    847       playout_timestamp_rtcp_(0),
    848       playout_delay_ms_(0),
    849       _numberOfDiscardedPackets(0),
    850       send_sequence_number_(0),
    851       ts_stats_lock_(CriticalSectionWrapper::CreateCriticalSection()),
    852       rtp_ts_wraparound_handler_(new rtc::TimestampWrapAroundHandler()),
    853       capture_start_rtp_time_stamp_(-1),
    854       capture_start_ntp_time_ms_(-1),
    855       _engineStatisticsPtr(NULL),
    856       _outputMixerPtr(NULL),
    857       _transmitMixerPtr(NULL),
    858       _moduleProcessThreadPtr(NULL),
    859       _audioDeviceModulePtr(NULL),
    860       _voiceEngineObserverPtr(NULL),
    861       _callbackCritSectPtr(NULL),
    862       _transportPtr(NULL),
    863       _rxVadObserverPtr(NULL),
    864       _oldVadDecision(-1),
    865       _sendFrameType(0),
    866       _externalMixing(false),
    867       _mixFileWithMicrophone(false),
    868       _mute(false),
    869       _panLeft(1.0f),
    870       _panRight(1.0f),
    871       _outputGain(1.0f),
    872       _playOutbandDtmfEvent(false),
    873       _playInbandDtmfEvent(false),
    874       _lastLocalTimeStamp(0),
    875       _lastPayloadType(0),
    876       _includeAudioLevelIndication(false),
    877       _outputSpeechType(AudioFrame::kNormalSpeech),
    878       video_sync_lock_(CriticalSectionWrapper::CreateCriticalSection()),
    879       _average_jitter_buffer_delay_us(0),
    880       _previousTimestamp(0),
    881       _recPacketDelayMs(20),
    882       _RxVadDetection(false),
    883       _rxAgcIsEnabled(false),
    884       _rxNsIsEnabled(false),
    885       restored_packet_in_use_(false),
    886       rtcp_observer_(new VoERtcpObserver(this)),
    887       network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())),
    888       assoc_send_channel_lock_(CriticalSectionWrapper::CreateCriticalSection()),
    889       associate_send_channel_(ChannelOwner(nullptr)),
    890       pacing_enabled_(config.Get<VoicePacing>().enabled),
    891       feedback_observer_proxy_(pacing_enabled_ ? new TransportFeedbackProxy()
    892                                                : nullptr),
    893       seq_num_allocator_proxy_(
    894           pacing_enabled_ ? new TransportSequenceNumberProxy() : nullptr),
    895       rtp_packet_sender_proxy_(pacing_enabled_ ? new RtpPacketSenderProxy()
    896                                                : nullptr) {
    897     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId),
    898                  "Channel::Channel() - ctor");
    899     AudioCodingModule::Config acm_config;
    900     acm_config.id = VoEModuleId(instanceId, channelId);
    901     if (config.Get<NetEqCapacityConfig>().enabled) {
    902       // Clamping the buffer capacity at 20 packets. While going lower will
    903       // probably work, it makes little sense.
    904       acm_config.neteq_config.max_packets_in_buffer =
    905           std::max(20, config.Get<NetEqCapacityConfig>().capacity);
    906     }
    907     acm_config.neteq_config.enable_fast_accelerate =
    908         config.Get<NetEqFastAccelerate>().enabled;
    909     audio_coding_.reset(AudioCodingModule::Create(acm_config));
    910 
    911     _inbandDtmfQueue.ResetDtmf();
    912     _inbandDtmfGenerator.Init();
    913     _outputAudioLevel.Clear();
    914 
    915     RtpRtcp::Configuration configuration;
    916     configuration.audio = true;
    917     configuration.outgoing_transport = this;
    918     configuration.audio_messages = this;
    919     configuration.receive_statistics = rtp_receive_statistics_.get();
    920     configuration.bandwidth_callback = rtcp_observer_.get();
    921     configuration.paced_sender = rtp_packet_sender_proxy_.get();
    922     configuration.transport_sequence_number_allocator =
    923         seq_num_allocator_proxy_.get();
    924     configuration.transport_feedback_callback = feedback_observer_proxy_.get();
    925 
    926     _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
    927 
    928     statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC()));
    929     rtp_receive_statistics_->RegisterRtcpStatisticsCallback(
    930         statistics_proxy_.get());
    931 
    932     Config audioproc_config;
    933     audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
    934     rx_audioproc_.reset(AudioProcessing::Create(audioproc_config));
    935 }
    936 
    937 Channel::~Channel()
    938 {
    939     rtp_receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
    940     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId),
    941                  "Channel::~Channel() - dtor");
    942 
    943     if (_outputExternalMedia)
    944     {
    945         DeRegisterExternalMediaProcessing(kPlaybackPerChannel);
    946     }
    947     if (channel_state_.Get().input_external_media)
    948     {
    949         DeRegisterExternalMediaProcessing(kRecordingPerChannel);
    950     }
    951     StopSend();
    952     StopPlayout();
    953 
    954     {
    955         CriticalSectionScoped cs(&_fileCritSect);
    956         if (_inputFilePlayerPtr)
    957         {
    958             _inputFilePlayerPtr->RegisterModuleFileCallback(NULL);
    959             _inputFilePlayerPtr->StopPlayingFile();
    960             FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
    961             _inputFilePlayerPtr = NULL;
    962         }
    963         if (_outputFilePlayerPtr)
    964         {
    965             _outputFilePlayerPtr->RegisterModuleFileCallback(NULL);
    966             _outputFilePlayerPtr->StopPlayingFile();
    967             FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
    968             _outputFilePlayerPtr = NULL;
    969         }
    970         if (_outputFileRecorderPtr)
    971         {
    972             _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
    973             _outputFileRecorderPtr->StopRecording();
    974             FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
    975             _outputFileRecorderPtr = NULL;
    976         }
    977     }
    978 
    979     // The order to safely shutdown modules in a channel is:
    980     // 1. De-register callbacks in modules
    981     // 2. De-register modules in process thread
    982     // 3. Destroy modules
    983     if (audio_coding_->RegisterTransportCallback(NULL) == -1)
    984     {
    985         WEBRTC_TRACE(kTraceWarning, kTraceVoice,
    986                      VoEId(_instanceId,_channelId),
    987                      "~Channel() failed to de-register transport callback"
    988                      " (Audio coding module)");
    989     }
    990     if (audio_coding_->RegisterVADCallback(NULL) == -1)
    991     {
    992         WEBRTC_TRACE(kTraceWarning, kTraceVoice,
    993                      VoEId(_instanceId,_channelId),
    994                      "~Channel() failed to de-register VAD callback"
    995                      " (Audio coding module)");
    996     }
    997     // De-register modules in process thread
    998     _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get());
    999 
   1000     // End of modules shutdown
   1001 
   1002     // Delete other objects
   1003     delete &_callbackCritSect;
   1004     delete &_fileCritSect;
   1005     delete &volume_settings_critsect_;
   1006 }
   1007 
   1008 int32_t
   1009 Channel::Init()
   1010 {
   1011     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1012                  "Channel::Init()");
   1013 
   1014     channel_state_.Reset();
   1015 
   1016     // --- Initial sanity
   1017 
   1018     if ((_engineStatisticsPtr == NULL) ||
   1019         (_moduleProcessThreadPtr == NULL))
   1020     {
   1021         WEBRTC_TRACE(kTraceError, kTraceVoice,
   1022                      VoEId(_instanceId,_channelId),
   1023                      "Channel::Init() must call SetEngineInformation() first");
   1024         return -1;
   1025     }
   1026 
   1027     // --- Add modules to process thread (for periodic schedulation)
   1028 
   1029     _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get());
   1030 
   1031     // --- ACM initialization
   1032 
   1033     if (audio_coding_->InitializeReceiver() == -1) {
   1034         _engineStatisticsPtr->SetLastError(
   1035             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1036             "Channel::Init() unable to initialize the ACM - 1");
   1037         return -1;
   1038     }
   1039 
   1040     // --- RTP/RTCP module initialization
   1041 
   1042     // Ensure that RTCP is enabled by default for the created channel.
   1043     // Note that, the module will keep generating RTCP until it is explicitly
   1044     // disabled by the user.
   1045     // After StopListen (when no sockets exists), RTCP packets will no longer
   1046     // be transmitted since the Transport object will then be invalid.
   1047     telephone_event_handler_->SetTelephoneEventForwardToDecoder(true);
   1048     // RTCP is enabled by default.
   1049     _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
   1050     // --- Register all permanent callbacks
   1051     const bool fail =
   1052         (audio_coding_->RegisterTransportCallback(this) == -1) ||
   1053         (audio_coding_->RegisterVADCallback(this) == -1);
   1054 
   1055     if (fail)
   1056     {
   1057         _engineStatisticsPtr->SetLastError(
   1058             VE_CANNOT_INIT_CHANNEL, kTraceError,
   1059             "Channel::Init() callbacks not registered");
   1060         return -1;
   1061     }
   1062 
   1063     // --- Register all supported codecs to the receiving side of the
   1064     // RTP/RTCP module
   1065 
   1066     CodecInst codec;
   1067     const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
   1068 
   1069     for (int idx = 0; idx < nSupportedCodecs; idx++)
   1070     {
   1071         // Open up the RTP/RTCP receiver for all supported codecs
   1072         if ((audio_coding_->Codec(idx, &codec) == -1) ||
   1073             (rtp_receiver_->RegisterReceivePayload(
   1074                 codec.plname,
   1075                 codec.pltype,
   1076                 codec.plfreq,
   1077                 codec.channels,
   1078                 (codec.rate < 0) ? 0 : codec.rate) == -1))
   1079         {
   1080             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   1081                          VoEId(_instanceId,_channelId),
   1082                          "Channel::Init() unable to register %s "
   1083                          "(%d/%d/%" PRIuS "/%d) to RTP/RTCP receiver",
   1084                          codec.plname, codec.pltype, codec.plfreq,
   1085                          codec.channels, codec.rate);
   1086         }
   1087         else
   1088         {
   1089             WEBRTC_TRACE(kTraceInfo, kTraceVoice,
   1090                          VoEId(_instanceId,_channelId),
   1091                          "Channel::Init() %s (%d/%d/%" PRIuS "/%d) has been "
   1092                          "added to the RTP/RTCP receiver",
   1093                          codec.plname, codec.pltype, codec.plfreq,
   1094                          codec.channels, codec.rate);
   1095         }
   1096 
   1097         // Ensure that PCMU is used as default codec on the sending side
   1098         if (!STR_CASE_CMP(codec.plname, "PCMU") && (codec.channels == 1))
   1099         {
   1100             SetSendCodec(codec);
   1101         }
   1102 
   1103         // Register default PT for outband 'telephone-event'
   1104         if (!STR_CASE_CMP(codec.plname, "telephone-event"))
   1105         {
   1106             if ((_rtpRtcpModule->RegisterSendPayload(codec) == -1) ||
   1107                 (audio_coding_->RegisterReceiveCodec(codec) == -1))
   1108             {
   1109                 WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   1110                              VoEId(_instanceId,_channelId),
   1111                              "Channel::Init() failed to register outband "
   1112                              "'telephone-event' (%d/%d) correctly",
   1113                              codec.pltype, codec.plfreq);
   1114             }
   1115         }
   1116 
   1117         if (!STR_CASE_CMP(codec.plname, "CN"))
   1118         {
   1119             if ((audio_coding_->RegisterSendCodec(codec) == -1) ||
   1120                 (audio_coding_->RegisterReceiveCodec(codec) == -1) ||
   1121                 (_rtpRtcpModule->RegisterSendPayload(codec) == -1))
   1122             {
   1123                 WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   1124                              VoEId(_instanceId,_channelId),
   1125                              "Channel::Init() failed to register CN (%d/%d) "
   1126                              "correctly - 1",
   1127                              codec.pltype, codec.plfreq);
   1128             }
   1129         }
   1130 #ifdef WEBRTC_CODEC_RED
   1131         // Register RED to the receiving side of the ACM.
   1132         // We will not receive an OnInitializeDecoder() callback for RED.
   1133         if (!STR_CASE_CMP(codec.plname, "RED"))
   1134         {
   1135             if (audio_coding_->RegisterReceiveCodec(codec) == -1)
   1136             {
   1137                 WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   1138                              VoEId(_instanceId,_channelId),
   1139                              "Channel::Init() failed to register RED (%d/%d) "
   1140                              "correctly",
   1141                              codec.pltype, codec.plfreq);
   1142             }
   1143         }
   1144 #endif
   1145     }
   1146 
   1147     if (rx_audioproc_->noise_suppression()->set_level(kDefaultNsMode) != 0) {
   1148       LOG(LS_ERROR) << "noise_suppression()->set_level(kDefaultNsMode) failed.";
   1149       return -1;
   1150     }
   1151     if (rx_audioproc_->gain_control()->set_mode(kDefaultRxAgcMode) != 0) {
   1152       LOG(LS_ERROR) << "gain_control()->set_mode(kDefaultRxAgcMode) failed.";
   1153       return -1;
   1154     }
   1155 
   1156     return 0;
   1157 }
   1158 
   1159 int32_t
   1160 Channel::SetEngineInformation(Statistics& engineStatistics,
   1161                               OutputMixer& outputMixer,
   1162                               voe::TransmitMixer& transmitMixer,
   1163                               ProcessThread& moduleProcessThread,
   1164                               AudioDeviceModule& audioDeviceModule,
   1165                               VoiceEngineObserver* voiceEngineObserver,
   1166                               CriticalSectionWrapper* callbackCritSect)
   1167 {
   1168     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1169                  "Channel::SetEngineInformation()");
   1170     _engineStatisticsPtr = &engineStatistics;
   1171     _outputMixerPtr = &outputMixer;
   1172     _transmitMixerPtr = &transmitMixer,
   1173     _moduleProcessThreadPtr = &moduleProcessThread;
   1174     _audioDeviceModulePtr = &audioDeviceModule;
   1175     _voiceEngineObserverPtr = voiceEngineObserver;
   1176     _callbackCritSectPtr = callbackCritSect;
   1177     return 0;
   1178 }
   1179 
   1180 int32_t
   1181 Channel::UpdateLocalTimeStamp()
   1182 {
   1183 
   1184     _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_);
   1185     return 0;
   1186 }
   1187 
   1188 void Channel::SetSink(rtc::scoped_ptr<AudioSinkInterface> sink) {
   1189   CriticalSectionScoped cs(&_callbackCritSect);
   1190   audio_sink_ = std::move(sink);
   1191 }
   1192 
   1193 int32_t
   1194 Channel::StartPlayout()
   1195 {
   1196     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1197                  "Channel::StartPlayout()");
   1198     if (channel_state_.Get().playing)
   1199     {
   1200         return 0;
   1201     }
   1202 
   1203     if (!_externalMixing) {
   1204         // Add participant as candidates for mixing.
   1205         if (_outputMixerPtr->SetMixabilityStatus(*this, true) != 0)
   1206         {
   1207             _engineStatisticsPtr->SetLastError(
   1208                 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
   1209                 "StartPlayout() failed to add participant to mixer");
   1210             return -1;
   1211         }
   1212     }
   1213 
   1214     channel_state_.SetPlaying(true);
   1215     if (RegisterFilePlayingToMixer() != 0)
   1216         return -1;
   1217 
   1218     return 0;
   1219 }
   1220 
   1221 int32_t
   1222 Channel::StopPlayout()
   1223 {
   1224     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1225                  "Channel::StopPlayout()");
   1226     if (!channel_state_.Get().playing)
   1227     {
   1228         return 0;
   1229     }
   1230 
   1231     if (!_externalMixing) {
   1232         // Remove participant as candidates for mixing
   1233         if (_outputMixerPtr->SetMixabilityStatus(*this, false) != 0)
   1234         {
   1235             _engineStatisticsPtr->SetLastError(
   1236                 VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
   1237                 "StopPlayout() failed to remove participant from mixer");
   1238             return -1;
   1239         }
   1240     }
   1241 
   1242     channel_state_.SetPlaying(false);
   1243     _outputAudioLevel.Clear();
   1244 
   1245     return 0;
   1246 }
   1247 
   1248 int32_t
   1249 Channel::StartSend()
   1250 {
   1251     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1252                  "Channel::StartSend()");
   1253     // Resume the previous sequence number which was reset by StopSend().
   1254     // This needs to be done before |sending| is set to true.
   1255     if (send_sequence_number_)
   1256       SetInitSequenceNumber(send_sequence_number_);
   1257 
   1258     if (channel_state_.Get().sending)
   1259     {
   1260       return 0;
   1261     }
   1262     channel_state_.SetSending(true);
   1263 
   1264     if (_rtpRtcpModule->SetSendingStatus(true) != 0)
   1265     {
   1266         _engineStatisticsPtr->SetLastError(
   1267             VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   1268             "StartSend() RTP/RTCP failed to start sending");
   1269         CriticalSectionScoped cs(&_callbackCritSect);
   1270         channel_state_.SetSending(false);
   1271         return -1;
   1272     }
   1273 
   1274     return 0;
   1275 }
   1276 
   1277 int32_t
   1278 Channel::StopSend()
   1279 {
   1280     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1281                  "Channel::StopSend()");
   1282     if (!channel_state_.Get().sending)
   1283     {
   1284       return 0;
   1285     }
   1286     channel_state_.SetSending(false);
   1287 
   1288     // Store the sequence number to be able to pick up the same sequence for
   1289     // the next StartSend(). This is needed for restarting device, otherwise
   1290     // it might cause libSRTP to complain about packets being replayed.
   1291     // TODO(xians): Remove this workaround after RtpRtcpModule's refactoring
   1292     // CL is landed. See issue
   1293     // https://code.google.com/p/webrtc/issues/detail?id=2111 .
   1294     send_sequence_number_ = _rtpRtcpModule->SequenceNumber();
   1295 
   1296     // Reset sending SSRC and sequence number and triggers direct transmission
   1297     // of RTCP BYE
   1298     if (_rtpRtcpModule->SetSendingStatus(false) == -1)
   1299     {
   1300         _engineStatisticsPtr->SetLastError(
   1301             VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
   1302             "StartSend() RTP/RTCP failed to stop sending");
   1303     }
   1304 
   1305     return 0;
   1306 }
   1307 
   1308 int32_t
   1309 Channel::StartReceiving()
   1310 {
   1311     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1312                  "Channel::StartReceiving()");
   1313     if (channel_state_.Get().receiving)
   1314     {
   1315         return 0;
   1316     }
   1317     channel_state_.SetReceiving(true);
   1318     _numberOfDiscardedPackets = 0;
   1319     return 0;
   1320 }
   1321 
   1322 int32_t
   1323 Channel::StopReceiving()
   1324 {
   1325     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1326                  "Channel::StopReceiving()");
   1327     if (!channel_state_.Get().receiving)
   1328     {
   1329         return 0;
   1330     }
   1331 
   1332     channel_state_.SetReceiving(false);
   1333     return 0;
   1334 }
   1335 
   1336 int32_t
   1337 Channel::RegisterVoiceEngineObserver(VoiceEngineObserver& observer)
   1338 {
   1339     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1340                  "Channel::RegisterVoiceEngineObserver()");
   1341     CriticalSectionScoped cs(&_callbackCritSect);
   1342 
   1343     if (_voiceEngineObserverPtr)
   1344     {
   1345         _engineStatisticsPtr->SetLastError(
   1346             VE_INVALID_OPERATION, kTraceError,
   1347             "RegisterVoiceEngineObserver() observer already enabled");
   1348         return -1;
   1349     }
   1350     _voiceEngineObserverPtr = &observer;
   1351     return 0;
   1352 }
   1353 
   1354 int32_t
   1355 Channel::DeRegisterVoiceEngineObserver()
   1356 {
   1357     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1358                  "Channel::DeRegisterVoiceEngineObserver()");
   1359     CriticalSectionScoped cs(&_callbackCritSect);
   1360 
   1361     if (!_voiceEngineObserverPtr)
   1362     {
   1363         _engineStatisticsPtr->SetLastError(
   1364             VE_INVALID_OPERATION, kTraceWarning,
   1365             "DeRegisterVoiceEngineObserver() observer already disabled");
   1366         return 0;
   1367     }
   1368     _voiceEngineObserverPtr = NULL;
   1369     return 0;
   1370 }
   1371 
   1372 int32_t
   1373 Channel::GetSendCodec(CodecInst& codec)
   1374 {
   1375   auto send_codec = audio_coding_->SendCodec();
   1376   if (send_codec) {
   1377     codec = *send_codec;
   1378     return 0;
   1379   }
   1380   return -1;
   1381 }
   1382 
   1383 int32_t
   1384 Channel::GetRecCodec(CodecInst& codec)
   1385 {
   1386     return (audio_coding_->ReceiveCodec(&codec));
   1387 }
   1388 
   1389 int32_t
   1390 Channel::SetSendCodec(const CodecInst& codec)
   1391 {
   1392     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1393                  "Channel::SetSendCodec()");
   1394 
   1395     if (audio_coding_->RegisterSendCodec(codec) != 0)
   1396     {
   1397         WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
   1398                      "SetSendCodec() failed to register codec to ACM");
   1399         return -1;
   1400     }
   1401 
   1402     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0)
   1403     {
   1404         _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
   1405         if (_rtpRtcpModule->RegisterSendPayload(codec) != 0)
   1406         {
   1407             WEBRTC_TRACE(
   1408                     kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
   1409                     "SetSendCodec() failed to register codec to"
   1410                     " RTP/RTCP module");
   1411             return -1;
   1412         }
   1413     }
   1414 
   1415     if (_rtpRtcpModule->SetAudioPacketSize(codec.pacsize) != 0)
   1416     {
   1417         WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
   1418                      "SetSendCodec() failed to set audio packet size");
   1419         return -1;
   1420     }
   1421 
   1422     return 0;
   1423 }
   1424 
   1425 void Channel::SetBitRate(int bitrate_bps) {
   1426   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   1427                "Channel::SetBitRate(bitrate_bps=%d)", bitrate_bps);
   1428   audio_coding_->SetBitRate(bitrate_bps);
   1429 }
   1430 
   1431 void Channel::OnIncomingFractionLoss(int fraction_lost) {
   1432   network_predictor_->UpdatePacketLossRate(fraction_lost);
   1433   uint8_t average_fraction_loss = network_predictor_->GetLossRate();
   1434 
   1435   // Normalizes rate to 0 - 100.
   1436   if (audio_coding_->SetPacketLossRate(
   1437       100 * average_fraction_loss / 255) != 0) {
   1438     assert(false);  // This should not happen.
   1439   }
   1440 }
   1441 
   1442 int32_t
   1443 Channel::SetVADStatus(bool enableVAD, ACMVADMode mode, bool disableDTX)
   1444 {
   1445     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1446                  "Channel::SetVADStatus(mode=%d)", mode);
   1447     assert(!(disableDTX && enableVAD));  // disableDTX mode is deprecated.
   1448     // To disable VAD, DTX must be disabled too
   1449     disableDTX = ((enableVAD == false) ? true : disableDTX);
   1450     if (audio_coding_->SetVAD(!disableDTX, enableVAD, mode) != 0)
   1451     {
   1452         _engineStatisticsPtr->SetLastError(
   1453             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1454             "SetVADStatus() failed to set VAD");
   1455         return -1;
   1456     }
   1457     return 0;
   1458 }
   1459 
   1460 int32_t
   1461 Channel::GetVADStatus(bool& enabledVAD, ACMVADMode& mode, bool& disabledDTX)
   1462 {
   1463     if (audio_coding_->VAD(&disabledDTX, &enabledVAD, &mode) != 0)
   1464     {
   1465         _engineStatisticsPtr->SetLastError(
   1466             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1467             "GetVADStatus() failed to get VAD status");
   1468         return -1;
   1469     }
   1470     disabledDTX = !disabledDTX;
   1471     return 0;
   1472 }
   1473 
   1474 int32_t
   1475 Channel::SetRecPayloadType(const CodecInst& codec)
   1476 {
   1477     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1478                  "Channel::SetRecPayloadType()");
   1479 
   1480     if (channel_state_.Get().playing)
   1481     {
   1482         _engineStatisticsPtr->SetLastError(
   1483             VE_ALREADY_PLAYING, kTraceError,
   1484             "SetRecPayloadType() unable to set PT while playing");
   1485         return -1;
   1486     }
   1487     if (channel_state_.Get().receiving)
   1488     {
   1489         _engineStatisticsPtr->SetLastError(
   1490             VE_ALREADY_LISTENING, kTraceError,
   1491             "SetRecPayloadType() unable to set PT while listening");
   1492         return -1;
   1493     }
   1494 
   1495     if (codec.pltype == -1)
   1496     {
   1497         // De-register the selected codec (RTP/RTCP module and ACM)
   1498 
   1499         int8_t pltype(-1);
   1500         CodecInst rxCodec = codec;
   1501 
   1502         // Get payload type for the given codec
   1503         rtp_payload_registry_->ReceivePayloadType(
   1504             rxCodec.plname,
   1505             rxCodec.plfreq,
   1506             rxCodec.channels,
   1507             (rxCodec.rate < 0) ? 0 : rxCodec.rate,
   1508             &pltype);
   1509         rxCodec.pltype = pltype;
   1510 
   1511         if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0)
   1512         {
   1513             _engineStatisticsPtr->SetLastError(
   1514                     VE_RTP_RTCP_MODULE_ERROR,
   1515                     kTraceError,
   1516                     "SetRecPayloadType() RTP/RTCP-module deregistration "
   1517                     "failed");
   1518             return -1;
   1519         }
   1520         if (audio_coding_->UnregisterReceiveCodec(rxCodec.pltype) != 0)
   1521         {
   1522             _engineStatisticsPtr->SetLastError(
   1523                 VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1524                 "SetRecPayloadType() ACM deregistration failed - 1");
   1525             return -1;
   1526         }
   1527         return 0;
   1528     }
   1529 
   1530     if (rtp_receiver_->RegisterReceivePayload(
   1531         codec.plname,
   1532         codec.pltype,
   1533         codec.plfreq,
   1534         codec.channels,
   1535         (codec.rate < 0) ? 0 : codec.rate) != 0)
   1536     {
   1537         // First attempt to register failed => de-register and try again
   1538         rtp_receiver_->DeRegisterReceivePayload(codec.pltype);
   1539         if (rtp_receiver_->RegisterReceivePayload(
   1540             codec.plname,
   1541             codec.pltype,
   1542             codec.plfreq,
   1543             codec.channels,
   1544             (codec.rate < 0) ? 0 : codec.rate) != 0)
   1545         {
   1546             _engineStatisticsPtr->SetLastError(
   1547                 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   1548                 "SetRecPayloadType() RTP/RTCP-module registration failed");
   1549             return -1;
   1550         }
   1551     }
   1552     if (audio_coding_->RegisterReceiveCodec(codec) != 0)
   1553     {
   1554         audio_coding_->UnregisterReceiveCodec(codec.pltype);
   1555         if (audio_coding_->RegisterReceiveCodec(codec) != 0)
   1556         {
   1557             _engineStatisticsPtr->SetLastError(
   1558                 VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1559                 "SetRecPayloadType() ACM registration failed - 1");
   1560             return -1;
   1561         }
   1562     }
   1563     return 0;
   1564 }
   1565 
   1566 int32_t
   1567 Channel::GetRecPayloadType(CodecInst& codec)
   1568 {
   1569     int8_t payloadType(-1);
   1570     if (rtp_payload_registry_->ReceivePayloadType(
   1571         codec.plname,
   1572         codec.plfreq,
   1573         codec.channels,
   1574         (codec.rate < 0) ? 0 : codec.rate,
   1575         &payloadType) != 0)
   1576     {
   1577         _engineStatisticsPtr->SetLastError(
   1578             VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
   1579             "GetRecPayloadType() failed to retrieve RX payload type");
   1580         return -1;
   1581     }
   1582     codec.pltype = payloadType;
   1583     return 0;
   1584 }
   1585 
   1586 int32_t
   1587 Channel::SetSendCNPayloadType(int type, PayloadFrequencies frequency)
   1588 {
   1589     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1590                  "Channel::SetSendCNPayloadType()");
   1591 
   1592     CodecInst codec;
   1593     int32_t samplingFreqHz(-1);
   1594     const size_t kMono = 1;
   1595     if (frequency == kFreq32000Hz)
   1596         samplingFreqHz = 32000;
   1597     else if (frequency == kFreq16000Hz)
   1598         samplingFreqHz = 16000;
   1599 
   1600     if (audio_coding_->Codec("CN", &codec, samplingFreqHz, kMono) == -1)
   1601     {
   1602         _engineStatisticsPtr->SetLastError(
   1603             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1604             "SetSendCNPayloadType() failed to retrieve default CN codec "
   1605             "settings");
   1606         return -1;
   1607     }
   1608 
   1609     // Modify the payload type (must be set to dynamic range)
   1610     codec.pltype = type;
   1611 
   1612     if (audio_coding_->RegisterSendCodec(codec) != 0)
   1613     {
   1614         _engineStatisticsPtr->SetLastError(
   1615             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1616             "SetSendCNPayloadType() failed to register CN to ACM");
   1617         return -1;
   1618     }
   1619 
   1620     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0)
   1621     {
   1622         _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
   1623         if (_rtpRtcpModule->RegisterSendPayload(codec) != 0)
   1624         {
   1625             _engineStatisticsPtr->SetLastError(
   1626                 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   1627                 "SetSendCNPayloadType() failed to register CN to RTP/RTCP "
   1628                 "module");
   1629             return -1;
   1630         }
   1631     }
   1632     return 0;
   1633 }
   1634 
   1635 int Channel::SetOpusMaxPlaybackRate(int frequency_hz) {
   1636   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   1637                "Channel::SetOpusMaxPlaybackRate()");
   1638 
   1639   if (audio_coding_->SetOpusMaxPlaybackRate(frequency_hz) != 0) {
   1640     _engineStatisticsPtr->SetLastError(
   1641         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   1642         "SetOpusMaxPlaybackRate() failed to set maximum playback rate");
   1643     return -1;
   1644   }
   1645   return 0;
   1646 }
   1647 
   1648 int Channel::SetOpusDtx(bool enable_dtx) {
   1649   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   1650                "Channel::SetOpusDtx(%d)", enable_dtx);
   1651   int ret = enable_dtx ? audio_coding_->EnableOpusDtx()
   1652                        : audio_coding_->DisableOpusDtx();
   1653   if (ret != 0) {
   1654     _engineStatisticsPtr->SetLastError(
   1655         VE_AUDIO_CODING_MODULE_ERROR, kTraceError, "SetOpusDtx() failed");
   1656     return -1;
   1657   }
   1658   return 0;
   1659 }
   1660 
   1661 int32_t Channel::RegisterExternalTransport(Transport& transport)
   1662 {
   1663     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   1664                "Channel::RegisterExternalTransport()");
   1665 
   1666     CriticalSectionScoped cs(&_callbackCritSect);
   1667 
   1668     if (_externalTransport)
   1669     {
   1670         _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION,
   1671                                            kTraceError,
   1672               "RegisterExternalTransport() external transport already enabled");
   1673        return -1;
   1674     }
   1675     _externalTransport = true;
   1676     _transportPtr = &transport;
   1677     return 0;
   1678 }
   1679 
   1680 int32_t
   1681 Channel::DeRegisterExternalTransport()
   1682 {
   1683     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1684                  "Channel::DeRegisterExternalTransport()");
   1685 
   1686     CriticalSectionScoped cs(&_callbackCritSect);
   1687 
   1688     if (!_transportPtr)
   1689     {
   1690         _engineStatisticsPtr->SetLastError(
   1691             VE_INVALID_OPERATION, kTraceWarning,
   1692             "DeRegisterExternalTransport() external transport already "
   1693             "disabled");
   1694         return 0;
   1695     }
   1696     _externalTransport = false;
   1697     _transportPtr = NULL;
   1698     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1699                  "DeRegisterExternalTransport() all transport is disabled");
   1700     return 0;
   1701 }
   1702 
   1703 int32_t Channel::ReceivedRTPPacket(const int8_t* data, size_t length,
   1704                                    const PacketTime& packet_time) {
   1705   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   1706                "Channel::ReceivedRTPPacket()");
   1707 
   1708   // Store playout timestamp for the received RTP packet
   1709   UpdatePlayoutTimestamp(false);
   1710 
   1711   const uint8_t* received_packet = reinterpret_cast<const uint8_t*>(data);
   1712   RTPHeader header;
   1713   if (!rtp_header_parser_->Parse(received_packet, length, &header)) {
   1714     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
   1715                  "Incoming packet: invalid RTP header");
   1716     return -1;
   1717   }
   1718   header.payload_type_frequency =
   1719       rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
   1720   if (header.payload_type_frequency < 0)
   1721     return -1;
   1722   bool in_order = IsPacketInOrder(header);
   1723   rtp_receive_statistics_->IncomingPacket(header, length,
   1724       IsPacketRetransmitted(header, in_order));
   1725   rtp_payload_registry_->SetIncomingPayloadType(header);
   1726 
   1727   return ReceivePacket(received_packet, length, header, in_order) ? 0 : -1;
   1728 }
   1729 
   1730 bool Channel::ReceivePacket(const uint8_t* packet,
   1731                             size_t packet_length,
   1732                             const RTPHeader& header,
   1733                             bool in_order) {
   1734   if (rtp_payload_registry_->IsRtx(header)) {
   1735     return HandleRtxPacket(packet, packet_length, header);
   1736   }
   1737   const uint8_t* payload = packet + header.headerLength;
   1738   assert(packet_length >= header.headerLength);
   1739   size_t payload_length = packet_length - header.headerLength;
   1740   PayloadUnion payload_specific;
   1741   if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
   1742                                                   &payload_specific)) {
   1743     return false;
   1744   }
   1745   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
   1746                                           payload_specific, in_order);
   1747 }
   1748 
   1749 bool Channel::HandleRtxPacket(const uint8_t* packet,
   1750                               size_t packet_length,
   1751                               const RTPHeader& header) {
   1752   if (!rtp_payload_registry_->IsRtx(header))
   1753     return false;
   1754 
   1755   // Remove the RTX header and parse the original RTP header.
   1756   if (packet_length < header.headerLength)
   1757     return false;
   1758   if (packet_length > kVoiceEngineMaxIpPacketSizeBytes)
   1759     return false;
   1760   if (restored_packet_in_use_) {
   1761     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
   1762                  "Multiple RTX headers detected, dropping packet");
   1763     return false;
   1764   }
   1765   if (!rtp_payload_registry_->RestoreOriginalPacket(
   1766           restored_packet_, packet, &packet_length, rtp_receiver_->SSRC(),
   1767           header)) {
   1768     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVoice, _channelId,
   1769                  "Incoming RTX packet: invalid RTP header");
   1770     return false;
   1771   }
   1772   restored_packet_in_use_ = true;
   1773   bool ret = OnRecoveredPacket(restored_packet_, packet_length);
   1774   restored_packet_in_use_ = false;
   1775   return ret;
   1776 }
   1777 
   1778 bool Channel::IsPacketInOrder(const RTPHeader& header) const {
   1779   StreamStatistician* statistician =
   1780       rtp_receive_statistics_->GetStatistician(header.ssrc);
   1781   if (!statistician)
   1782     return false;
   1783   return statistician->IsPacketInOrder(header.sequenceNumber);
   1784 }
   1785 
   1786 bool Channel::IsPacketRetransmitted(const RTPHeader& header,
   1787                                     bool in_order) const {
   1788   // Retransmissions are handled separately if RTX is enabled.
   1789   if (rtp_payload_registry_->RtxEnabled())
   1790     return false;
   1791   StreamStatistician* statistician =
   1792       rtp_receive_statistics_->GetStatistician(header.ssrc);
   1793   if (!statistician)
   1794     return false;
   1795   // Check if this is a retransmission.
   1796   int64_t min_rtt = 0;
   1797   _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
   1798   return !in_order &&
   1799       statistician->IsRetransmitOfOldPacket(header, min_rtt);
   1800 }
   1801 
   1802 int32_t Channel::ReceivedRTCPPacket(const int8_t* data, size_t length) {
   1803   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   1804                "Channel::ReceivedRTCPPacket()");
   1805   // Store playout timestamp for the received RTCP packet
   1806   UpdatePlayoutTimestamp(true);
   1807 
   1808   // Deliver RTCP packet to RTP/RTCP module for parsing
   1809   if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, length) == -1) {
   1810     _engineStatisticsPtr->SetLastError(
   1811         VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
   1812         "Channel::IncomingRTPPacket() RTCP packet is invalid");
   1813   }
   1814 
   1815   int64_t rtt = GetRTT(true);
   1816   if (rtt == 0) {
   1817     // Waiting for valid RTT.
   1818     return 0;
   1819   }
   1820   uint32_t ntp_secs = 0;
   1821   uint32_t ntp_frac = 0;
   1822   uint32_t rtp_timestamp = 0;
   1823   if (0 != _rtpRtcpModule->RemoteNTP(&ntp_secs, &ntp_frac, NULL, NULL,
   1824                                      &rtp_timestamp)) {
   1825     // Waiting for RTCP.
   1826     return 0;
   1827   }
   1828 
   1829   {
   1830     CriticalSectionScoped lock(ts_stats_lock_.get());
   1831     ntp_estimator_.UpdateRtcpTimestamp(rtt, ntp_secs, ntp_frac, rtp_timestamp);
   1832   }
   1833   return 0;
   1834 }
   1835 
   1836 int Channel::StartPlayingFileLocally(const char* fileName,
   1837                                      bool loop,
   1838                                      FileFormats format,
   1839                                      int startPosition,
   1840                                      float volumeScaling,
   1841                                      int stopPosition,
   1842                                      const CodecInst* codecInst)
   1843 {
   1844     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1845                  "Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d,"
   1846                  " format=%d, volumeScaling=%5.3f, startPosition=%d, "
   1847                  "stopPosition=%d)", fileName, loop, format, volumeScaling,
   1848                  startPosition, stopPosition);
   1849 
   1850     if (channel_state_.Get().output_file_playing)
   1851     {
   1852         _engineStatisticsPtr->SetLastError(
   1853             VE_ALREADY_PLAYING, kTraceError,
   1854             "StartPlayingFileLocally() is already playing");
   1855         return -1;
   1856     }
   1857 
   1858     {
   1859         CriticalSectionScoped cs(&_fileCritSect);
   1860 
   1861         if (_outputFilePlayerPtr)
   1862         {
   1863             _outputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   1864             FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   1865             _outputFilePlayerPtr = NULL;
   1866         }
   1867 
   1868         _outputFilePlayerPtr = FilePlayer::CreateFilePlayer(
   1869             _outputFilePlayerId, (const FileFormats)format);
   1870 
   1871         if (_outputFilePlayerPtr == NULL)
   1872         {
   1873             _engineStatisticsPtr->SetLastError(
   1874                 VE_INVALID_ARGUMENT, kTraceError,
   1875                 "StartPlayingFileLocally() filePlayer format is not correct");
   1876             return -1;
   1877         }
   1878 
   1879         const uint32_t notificationTime(0);
   1880 
   1881         if (_outputFilePlayerPtr->StartPlayingFile(
   1882                 fileName,
   1883                 loop,
   1884                 startPosition,
   1885                 volumeScaling,
   1886                 notificationTime,
   1887                 stopPosition,
   1888                 (const CodecInst*)codecInst) != 0)
   1889         {
   1890             _engineStatisticsPtr->SetLastError(
   1891                 VE_BAD_FILE, kTraceError,
   1892                 "StartPlayingFile() failed to start file playout");
   1893             _outputFilePlayerPtr->StopPlayingFile();
   1894             FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   1895             _outputFilePlayerPtr = NULL;
   1896             return -1;
   1897         }
   1898         _outputFilePlayerPtr->RegisterModuleFileCallback(this);
   1899         channel_state_.SetOutputFilePlaying(true);
   1900     }
   1901 
   1902     if (RegisterFilePlayingToMixer() != 0)
   1903         return -1;
   1904 
   1905     return 0;
   1906 }
   1907 
   1908 int Channel::StartPlayingFileLocally(InStream* stream,
   1909                                      FileFormats format,
   1910                                      int startPosition,
   1911                                      float volumeScaling,
   1912                                      int stopPosition,
   1913                                      const CodecInst* codecInst)
   1914 {
   1915     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1916                  "Channel::StartPlayingFileLocally(format=%d,"
   1917                  " volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)",
   1918                  format, volumeScaling, startPosition, stopPosition);
   1919 
   1920     if(stream == NULL)
   1921     {
   1922         _engineStatisticsPtr->SetLastError(
   1923             VE_BAD_FILE, kTraceError,
   1924             "StartPlayingFileLocally() NULL as input stream");
   1925         return -1;
   1926     }
   1927 
   1928 
   1929     if (channel_state_.Get().output_file_playing)
   1930     {
   1931         _engineStatisticsPtr->SetLastError(
   1932             VE_ALREADY_PLAYING, kTraceError,
   1933             "StartPlayingFileLocally() is already playing");
   1934         return -1;
   1935     }
   1936 
   1937     {
   1938       CriticalSectionScoped cs(&_fileCritSect);
   1939 
   1940       // Destroy the old instance
   1941       if (_outputFilePlayerPtr)
   1942       {
   1943           _outputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   1944           FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   1945           _outputFilePlayerPtr = NULL;
   1946       }
   1947 
   1948       // Create the instance
   1949       _outputFilePlayerPtr = FilePlayer::CreateFilePlayer(
   1950           _outputFilePlayerId,
   1951           (const FileFormats)format);
   1952 
   1953       if (_outputFilePlayerPtr == NULL)
   1954       {
   1955           _engineStatisticsPtr->SetLastError(
   1956               VE_INVALID_ARGUMENT, kTraceError,
   1957               "StartPlayingFileLocally() filePlayer format isnot correct");
   1958           return -1;
   1959       }
   1960 
   1961       const uint32_t notificationTime(0);
   1962 
   1963       if (_outputFilePlayerPtr->StartPlayingFile(*stream, startPosition,
   1964                                                  volumeScaling,
   1965                                                  notificationTime,
   1966                                                  stopPosition, codecInst) != 0)
   1967       {
   1968           _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
   1969                                              "StartPlayingFile() failed to "
   1970                                              "start file playout");
   1971           _outputFilePlayerPtr->StopPlayingFile();
   1972           FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   1973           _outputFilePlayerPtr = NULL;
   1974           return -1;
   1975       }
   1976       _outputFilePlayerPtr->RegisterModuleFileCallback(this);
   1977       channel_state_.SetOutputFilePlaying(true);
   1978     }
   1979 
   1980     if (RegisterFilePlayingToMixer() != 0)
   1981         return -1;
   1982 
   1983     return 0;
   1984 }
   1985 
   1986 int Channel::StopPlayingFileLocally()
   1987 {
   1988     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   1989                  "Channel::StopPlayingFileLocally()");
   1990 
   1991     if (!channel_state_.Get().output_file_playing)
   1992     {
   1993         return 0;
   1994     }
   1995 
   1996     {
   1997         CriticalSectionScoped cs(&_fileCritSect);
   1998 
   1999         if (_outputFilePlayerPtr->StopPlayingFile() != 0)
   2000         {
   2001             _engineStatisticsPtr->SetLastError(
   2002                 VE_STOP_RECORDING_FAILED, kTraceError,
   2003                 "StopPlayingFile() could not stop playing");
   2004             return -1;
   2005         }
   2006         _outputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   2007         FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   2008         _outputFilePlayerPtr = NULL;
   2009         channel_state_.SetOutputFilePlaying(false);
   2010     }
   2011     // _fileCritSect cannot be taken while calling
   2012     // SetAnonymousMixibilityStatus. Refer to comments in
   2013     // StartPlayingFileLocally(const char* ...) for more details.
   2014     if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, false) != 0)
   2015     {
   2016         _engineStatisticsPtr->SetLastError(
   2017             VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
   2018             "StopPlayingFile() failed to stop participant from playing as"
   2019             "file in the mixer");
   2020         return -1;
   2021     }
   2022 
   2023     return 0;
   2024 }
   2025 
   2026 int Channel::IsPlayingFileLocally() const
   2027 {
   2028     return channel_state_.Get().output_file_playing;
   2029 }
   2030 
   2031 int Channel::RegisterFilePlayingToMixer()
   2032 {
   2033     // Return success for not registering for file playing to mixer if:
   2034     // 1. playing file before playout is started on that channel.
   2035     // 2. starting playout without file playing on that channel.
   2036     if (!channel_state_.Get().playing ||
   2037         !channel_state_.Get().output_file_playing)
   2038     {
   2039         return 0;
   2040     }
   2041 
   2042     // |_fileCritSect| cannot be taken while calling
   2043     // SetAnonymousMixabilityStatus() since as soon as the participant is added
   2044     // frames can be pulled by the mixer. Since the frames are generated from
   2045     // the file, _fileCritSect will be taken. This would result in a deadlock.
   2046     if (_outputMixerPtr->SetAnonymousMixabilityStatus(*this, true) != 0)
   2047     {
   2048         channel_state_.SetOutputFilePlaying(false);
   2049         CriticalSectionScoped cs(&_fileCritSect);
   2050         _engineStatisticsPtr->SetLastError(
   2051             VE_AUDIO_CONF_MIX_MODULE_ERROR, kTraceError,
   2052             "StartPlayingFile() failed to add participant as file to mixer");
   2053         _outputFilePlayerPtr->StopPlayingFile();
   2054         FilePlayer::DestroyFilePlayer(_outputFilePlayerPtr);
   2055         _outputFilePlayerPtr = NULL;
   2056         return -1;
   2057     }
   2058 
   2059     return 0;
   2060 }
   2061 
   2062 int Channel::StartPlayingFileAsMicrophone(const char* fileName,
   2063                                           bool loop,
   2064                                           FileFormats format,
   2065                                           int startPosition,
   2066                                           float volumeScaling,
   2067                                           int stopPosition,
   2068                                           const CodecInst* codecInst)
   2069 {
   2070     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2071                  "Channel::StartPlayingFileAsMicrophone(fileNameUTF8[]=%s, "
   2072                  "loop=%d, format=%d, volumeScaling=%5.3f, startPosition=%d, "
   2073                  "stopPosition=%d)", fileName, loop, format, volumeScaling,
   2074                  startPosition, stopPosition);
   2075 
   2076     CriticalSectionScoped cs(&_fileCritSect);
   2077 
   2078     if (channel_state_.Get().input_file_playing)
   2079     {
   2080         _engineStatisticsPtr->SetLastError(
   2081             VE_ALREADY_PLAYING, kTraceWarning,
   2082             "StartPlayingFileAsMicrophone() filePlayer is playing");
   2083         return 0;
   2084     }
   2085 
   2086     // Destroy the old instance
   2087     if (_inputFilePlayerPtr)
   2088     {
   2089         _inputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   2090         FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
   2091         _inputFilePlayerPtr = NULL;
   2092     }
   2093 
   2094     // Create the instance
   2095     _inputFilePlayerPtr = FilePlayer::CreateFilePlayer(
   2096         _inputFilePlayerId, (const FileFormats)format);
   2097 
   2098     if (_inputFilePlayerPtr == NULL)
   2099     {
   2100         _engineStatisticsPtr->SetLastError(
   2101             VE_INVALID_ARGUMENT, kTraceError,
   2102             "StartPlayingFileAsMicrophone() filePlayer format isnot correct");
   2103         return -1;
   2104     }
   2105 
   2106     const uint32_t notificationTime(0);
   2107 
   2108     if (_inputFilePlayerPtr->StartPlayingFile(
   2109         fileName,
   2110         loop,
   2111         startPosition,
   2112         volumeScaling,
   2113         notificationTime,
   2114         stopPosition,
   2115         (const CodecInst*)codecInst) != 0)
   2116     {
   2117         _engineStatisticsPtr->SetLastError(
   2118             VE_BAD_FILE, kTraceError,
   2119             "StartPlayingFile() failed to start file playout");
   2120         _inputFilePlayerPtr->StopPlayingFile();
   2121         FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
   2122         _inputFilePlayerPtr = NULL;
   2123         return -1;
   2124     }
   2125     _inputFilePlayerPtr->RegisterModuleFileCallback(this);
   2126     channel_state_.SetInputFilePlaying(true);
   2127 
   2128     return 0;
   2129 }
   2130 
   2131 int Channel::StartPlayingFileAsMicrophone(InStream* stream,
   2132                                           FileFormats format,
   2133                                           int startPosition,
   2134                                           float volumeScaling,
   2135                                           int stopPosition,
   2136                                           const CodecInst* codecInst)
   2137 {
   2138     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2139                  "Channel::StartPlayingFileAsMicrophone(format=%d, "
   2140                  "volumeScaling=%5.3f, startPosition=%d, stopPosition=%d)",
   2141                  format, volumeScaling, startPosition, stopPosition);
   2142 
   2143     if(stream == NULL)
   2144     {
   2145         _engineStatisticsPtr->SetLastError(
   2146             VE_BAD_FILE, kTraceError,
   2147             "StartPlayingFileAsMicrophone NULL as input stream");
   2148         return -1;
   2149     }
   2150 
   2151     CriticalSectionScoped cs(&_fileCritSect);
   2152 
   2153     if (channel_state_.Get().input_file_playing)
   2154     {
   2155         _engineStatisticsPtr->SetLastError(
   2156             VE_ALREADY_PLAYING, kTraceWarning,
   2157             "StartPlayingFileAsMicrophone() is playing");
   2158         return 0;
   2159     }
   2160 
   2161     // Destroy the old instance
   2162     if (_inputFilePlayerPtr)
   2163     {
   2164         _inputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   2165         FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
   2166         _inputFilePlayerPtr = NULL;
   2167     }
   2168 
   2169     // Create the instance
   2170     _inputFilePlayerPtr = FilePlayer::CreateFilePlayer(
   2171         _inputFilePlayerId, (const FileFormats)format);
   2172 
   2173     if (_inputFilePlayerPtr == NULL)
   2174     {
   2175         _engineStatisticsPtr->SetLastError(
   2176             VE_INVALID_ARGUMENT, kTraceError,
   2177             "StartPlayingInputFile() filePlayer format isnot correct");
   2178         return -1;
   2179     }
   2180 
   2181     const uint32_t notificationTime(0);
   2182 
   2183     if (_inputFilePlayerPtr->StartPlayingFile(*stream, startPosition,
   2184                                               volumeScaling, notificationTime,
   2185                                               stopPosition, codecInst) != 0)
   2186     {
   2187         _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
   2188                                            "StartPlayingFile() failed to start "
   2189                                            "file playout");
   2190         _inputFilePlayerPtr->StopPlayingFile();
   2191         FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
   2192         _inputFilePlayerPtr = NULL;
   2193         return -1;
   2194     }
   2195 
   2196     _inputFilePlayerPtr->RegisterModuleFileCallback(this);
   2197     channel_state_.SetInputFilePlaying(true);
   2198 
   2199     return 0;
   2200 }
   2201 
   2202 int Channel::StopPlayingFileAsMicrophone()
   2203 {
   2204     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2205                  "Channel::StopPlayingFileAsMicrophone()");
   2206 
   2207     CriticalSectionScoped cs(&_fileCritSect);
   2208 
   2209     if (!channel_state_.Get().input_file_playing)
   2210     {
   2211         return 0;
   2212     }
   2213 
   2214     if (_inputFilePlayerPtr->StopPlayingFile() != 0)
   2215     {
   2216         _engineStatisticsPtr->SetLastError(
   2217             VE_STOP_RECORDING_FAILED, kTraceError,
   2218             "StopPlayingFile() could not stop playing");
   2219         return -1;
   2220     }
   2221     _inputFilePlayerPtr->RegisterModuleFileCallback(NULL);
   2222     FilePlayer::DestroyFilePlayer(_inputFilePlayerPtr);
   2223     _inputFilePlayerPtr = NULL;
   2224     channel_state_.SetInputFilePlaying(false);
   2225 
   2226     return 0;
   2227 }
   2228 
   2229 int Channel::IsPlayingFileAsMicrophone() const
   2230 {
   2231     return channel_state_.Get().input_file_playing;
   2232 }
   2233 
   2234 int Channel::StartRecordingPlayout(const char* fileName,
   2235                                    const CodecInst* codecInst)
   2236 {
   2237     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2238                  "Channel::StartRecordingPlayout(fileName=%s)", fileName);
   2239 
   2240     if (_outputFileRecording)
   2241     {
   2242         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1),
   2243                      "StartRecordingPlayout() is already recording");
   2244         return 0;
   2245     }
   2246 
   2247     FileFormats format;
   2248     const uint32_t notificationTime(0); // Not supported in VoE
   2249     CodecInst dummyCodec={100,"L16",16000,320,1,320000};
   2250 
   2251     if ((codecInst != NULL) &&
   2252       ((codecInst->channels < 1) || (codecInst->channels > 2)))
   2253     {
   2254         _engineStatisticsPtr->SetLastError(
   2255             VE_BAD_ARGUMENT, kTraceError,
   2256             "StartRecordingPlayout() invalid compression");
   2257         return(-1);
   2258     }
   2259     if(codecInst == NULL)
   2260     {
   2261         format = kFileFormatPcm16kHzFile;
   2262         codecInst=&dummyCodec;
   2263     }
   2264     else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
   2265         (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
   2266         (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
   2267     {
   2268         format = kFileFormatWavFile;
   2269     }
   2270     else
   2271     {
   2272         format = kFileFormatCompressedFile;
   2273     }
   2274 
   2275     CriticalSectionScoped cs(&_fileCritSect);
   2276 
   2277     // Destroy the old instance
   2278     if (_outputFileRecorderPtr)
   2279     {
   2280         _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
   2281         FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
   2282         _outputFileRecorderPtr = NULL;
   2283     }
   2284 
   2285     _outputFileRecorderPtr = FileRecorder::CreateFileRecorder(
   2286         _outputFileRecorderId, (const FileFormats)format);
   2287     if (_outputFileRecorderPtr == NULL)
   2288     {
   2289         _engineStatisticsPtr->SetLastError(
   2290             VE_INVALID_ARGUMENT, kTraceError,
   2291             "StartRecordingPlayout() fileRecorder format isnot correct");
   2292         return -1;
   2293     }
   2294 
   2295     if (_outputFileRecorderPtr->StartRecordingAudioFile(
   2296         fileName, (const CodecInst&)*codecInst, notificationTime) != 0)
   2297     {
   2298         _engineStatisticsPtr->SetLastError(
   2299             VE_BAD_FILE, kTraceError,
   2300             "StartRecordingAudioFile() failed to start file recording");
   2301         _outputFileRecorderPtr->StopRecording();
   2302         FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
   2303         _outputFileRecorderPtr = NULL;
   2304         return -1;
   2305     }
   2306     _outputFileRecorderPtr->RegisterModuleFileCallback(this);
   2307     _outputFileRecording = true;
   2308 
   2309     return 0;
   2310 }
   2311 
   2312 int Channel::StartRecordingPlayout(OutStream* stream,
   2313                                    const CodecInst* codecInst)
   2314 {
   2315     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2316                  "Channel::StartRecordingPlayout()");
   2317 
   2318     if (_outputFileRecording)
   2319     {
   2320         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,-1),
   2321                      "StartRecordingPlayout() is already recording");
   2322         return 0;
   2323     }
   2324 
   2325     FileFormats format;
   2326     const uint32_t notificationTime(0); // Not supported in VoE
   2327     CodecInst dummyCodec={100,"L16",16000,320,1,320000};
   2328 
   2329     if (codecInst != NULL && codecInst->channels != 1)
   2330     {
   2331         _engineStatisticsPtr->SetLastError(
   2332             VE_BAD_ARGUMENT, kTraceError,
   2333             "StartRecordingPlayout() invalid compression");
   2334         return(-1);
   2335     }
   2336     if(codecInst == NULL)
   2337     {
   2338         format = kFileFormatPcm16kHzFile;
   2339         codecInst=&dummyCodec;
   2340     }
   2341     else if((STR_CASE_CMP(codecInst->plname,"L16") == 0) ||
   2342         (STR_CASE_CMP(codecInst->plname,"PCMU") == 0) ||
   2343         (STR_CASE_CMP(codecInst->plname,"PCMA") == 0))
   2344     {
   2345         format = kFileFormatWavFile;
   2346     }
   2347     else
   2348     {
   2349         format = kFileFormatCompressedFile;
   2350     }
   2351 
   2352     CriticalSectionScoped cs(&_fileCritSect);
   2353 
   2354     // Destroy the old instance
   2355     if (_outputFileRecorderPtr)
   2356     {
   2357         _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
   2358         FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
   2359         _outputFileRecorderPtr = NULL;
   2360     }
   2361 
   2362     _outputFileRecorderPtr = FileRecorder::CreateFileRecorder(
   2363         _outputFileRecorderId, (const FileFormats)format);
   2364     if (_outputFileRecorderPtr == NULL)
   2365     {
   2366         _engineStatisticsPtr->SetLastError(
   2367             VE_INVALID_ARGUMENT, kTraceError,
   2368             "StartRecordingPlayout() fileRecorder format isnot correct");
   2369         return -1;
   2370     }
   2371 
   2372     if (_outputFileRecorderPtr->StartRecordingAudioFile(*stream, *codecInst,
   2373                                                         notificationTime) != 0)
   2374     {
   2375         _engineStatisticsPtr->SetLastError(VE_BAD_FILE, kTraceError,
   2376                                            "StartRecordingPlayout() failed to "
   2377                                            "start file recording");
   2378         _outputFileRecorderPtr->StopRecording();
   2379         FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
   2380         _outputFileRecorderPtr = NULL;
   2381         return -1;
   2382     }
   2383 
   2384     _outputFileRecorderPtr->RegisterModuleFileCallback(this);
   2385     _outputFileRecording = true;
   2386 
   2387     return 0;
   2388 }
   2389 
   2390 int Channel::StopRecordingPlayout()
   2391 {
   2392     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,-1),
   2393                  "Channel::StopRecordingPlayout()");
   2394 
   2395     if (!_outputFileRecording)
   2396     {
   2397         WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,-1),
   2398                      "StopRecordingPlayout() isnot recording");
   2399         return -1;
   2400     }
   2401 
   2402 
   2403     CriticalSectionScoped cs(&_fileCritSect);
   2404 
   2405     if (_outputFileRecorderPtr->StopRecording() != 0)
   2406     {
   2407         _engineStatisticsPtr->SetLastError(
   2408             VE_STOP_RECORDING_FAILED, kTraceError,
   2409             "StopRecording() could not stop recording");
   2410         return(-1);
   2411     }
   2412     _outputFileRecorderPtr->RegisterModuleFileCallback(NULL);
   2413     FileRecorder::DestroyFileRecorder(_outputFileRecorderPtr);
   2414     _outputFileRecorderPtr = NULL;
   2415     _outputFileRecording = false;
   2416 
   2417     return 0;
   2418 }
   2419 
   2420 void
   2421 Channel::SetMixWithMicStatus(bool mix)
   2422 {
   2423     CriticalSectionScoped cs(&_fileCritSect);
   2424     _mixFileWithMicrophone=mix;
   2425 }
   2426 
   2427 int
   2428 Channel::GetSpeechOutputLevel(uint32_t& level) const
   2429 {
   2430     int8_t currentLevel = _outputAudioLevel.Level();
   2431     level = static_cast<int32_t> (currentLevel);
   2432     return 0;
   2433 }
   2434 
   2435 int
   2436 Channel::GetSpeechOutputLevelFullRange(uint32_t& level) const
   2437 {
   2438     int16_t currentLevel = _outputAudioLevel.LevelFullRange();
   2439     level = static_cast<int32_t> (currentLevel);
   2440     return 0;
   2441 }
   2442 
   2443 int
   2444 Channel::SetMute(bool enable)
   2445 {
   2446     CriticalSectionScoped cs(&volume_settings_critsect_);
   2447     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2448                "Channel::SetMute(enable=%d)", enable);
   2449     _mute = enable;
   2450     return 0;
   2451 }
   2452 
   2453 bool
   2454 Channel::Mute() const
   2455 {
   2456     CriticalSectionScoped cs(&volume_settings_critsect_);
   2457     return _mute;
   2458 }
   2459 
   2460 int
   2461 Channel::SetOutputVolumePan(float left, float right)
   2462 {
   2463     CriticalSectionScoped cs(&volume_settings_critsect_);
   2464     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2465                "Channel::SetOutputVolumePan()");
   2466     _panLeft = left;
   2467     _panRight = right;
   2468     return 0;
   2469 }
   2470 
   2471 int
   2472 Channel::GetOutputVolumePan(float& left, float& right) const
   2473 {
   2474     CriticalSectionScoped cs(&volume_settings_critsect_);
   2475     left = _panLeft;
   2476     right = _panRight;
   2477     return 0;
   2478 }
   2479 
   2480 int
   2481 Channel::SetChannelOutputVolumeScaling(float scaling)
   2482 {
   2483     CriticalSectionScoped cs(&volume_settings_critsect_);
   2484     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2485                "Channel::SetChannelOutputVolumeScaling()");
   2486     _outputGain = scaling;
   2487     return 0;
   2488 }
   2489 
   2490 int
   2491 Channel::GetChannelOutputVolumeScaling(float& scaling) const
   2492 {
   2493     CriticalSectionScoped cs(&volume_settings_critsect_);
   2494     scaling = _outputGain;
   2495     return 0;
   2496 }
   2497 
   2498 int Channel::SendTelephoneEventOutband(unsigned char eventCode,
   2499                                        int lengthMs, int attenuationDb,
   2500                                        bool playDtmfEvent)
   2501 {
   2502     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   2503                "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)",
   2504                playDtmfEvent);
   2505     if (!Sending()) {
   2506       return -1;
   2507     }
   2508 
   2509     _playOutbandDtmfEvent = playDtmfEvent;
   2510 
   2511     if (_rtpRtcpModule->SendTelephoneEventOutband(eventCode, lengthMs,
   2512                                                  attenuationDb) != 0)
   2513     {
   2514         _engineStatisticsPtr->SetLastError(
   2515             VE_SEND_DTMF_FAILED,
   2516             kTraceWarning,
   2517             "SendTelephoneEventOutband() failed to send event");
   2518         return -1;
   2519     }
   2520     return 0;
   2521 }
   2522 
   2523 int Channel::SendTelephoneEventInband(unsigned char eventCode,
   2524                                          int lengthMs,
   2525                                          int attenuationDb,
   2526                                          bool playDtmfEvent)
   2527 {
   2528     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   2529                "Channel::SendTelephoneEventInband(..., playDtmfEvent=%d)",
   2530                playDtmfEvent);
   2531 
   2532     _playInbandDtmfEvent = playDtmfEvent;
   2533     _inbandDtmfQueue.AddDtmf(eventCode, lengthMs, attenuationDb);
   2534 
   2535     return 0;
   2536 }
   2537 
   2538 int
   2539 Channel::SetSendTelephoneEventPayloadType(unsigned char type)
   2540 {
   2541     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2542                "Channel::SetSendTelephoneEventPayloadType()");
   2543     if (type > 127)
   2544     {
   2545         _engineStatisticsPtr->SetLastError(
   2546             VE_INVALID_ARGUMENT, kTraceError,
   2547             "SetSendTelephoneEventPayloadType() invalid type");
   2548         return -1;
   2549     }
   2550     CodecInst codec = {};
   2551     codec.plfreq = 8000;
   2552     codec.pltype = type;
   2553     memcpy(codec.plname, "telephone-event", 16);
   2554     if (_rtpRtcpModule->RegisterSendPayload(codec) != 0)
   2555     {
   2556         _rtpRtcpModule->DeRegisterSendPayload(codec.pltype);
   2557         if (_rtpRtcpModule->RegisterSendPayload(codec) != 0) {
   2558             _engineStatisticsPtr->SetLastError(
   2559                 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   2560                 "SetSendTelephoneEventPayloadType() failed to register send"
   2561                 "payload type");
   2562             return -1;
   2563         }
   2564     }
   2565     _sendTelephoneEventPayloadType = type;
   2566     return 0;
   2567 }
   2568 
   2569 int
   2570 Channel::GetSendTelephoneEventPayloadType(unsigned char& type)
   2571 {
   2572     type = _sendTelephoneEventPayloadType;
   2573     return 0;
   2574 }
   2575 
   2576 int
   2577 Channel::UpdateRxVadDetection(AudioFrame& audioFrame)
   2578 {
   2579     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   2580                  "Channel::UpdateRxVadDetection()");
   2581 
   2582     int vadDecision = 1;
   2583 
   2584     vadDecision = (audioFrame.vad_activity_ == AudioFrame::kVadActive)? 1 : 0;
   2585 
   2586     if ((vadDecision != _oldVadDecision) && _rxVadObserverPtr)
   2587     {
   2588         OnRxVadDetected(vadDecision);
   2589         _oldVadDecision = vadDecision;
   2590     }
   2591 
   2592     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   2593                  "Channel::UpdateRxVadDetection() => vadDecision=%d",
   2594                  vadDecision);
   2595     return 0;
   2596 }
   2597 
   2598 int
   2599 Channel::RegisterRxVadObserver(VoERxVadCallback &observer)
   2600 {
   2601     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2602                  "Channel::RegisterRxVadObserver()");
   2603     CriticalSectionScoped cs(&_callbackCritSect);
   2604 
   2605     if (_rxVadObserverPtr)
   2606     {
   2607         _engineStatisticsPtr->SetLastError(
   2608             VE_INVALID_OPERATION, kTraceError,
   2609             "RegisterRxVadObserver() observer already enabled");
   2610         return -1;
   2611     }
   2612     _rxVadObserverPtr = &observer;
   2613     _RxVadDetection = true;
   2614     return 0;
   2615 }
   2616 
   2617 int
   2618 Channel::DeRegisterRxVadObserver()
   2619 {
   2620     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2621                  "Channel::DeRegisterRxVadObserver()");
   2622     CriticalSectionScoped cs(&_callbackCritSect);
   2623 
   2624     if (!_rxVadObserverPtr)
   2625     {
   2626         _engineStatisticsPtr->SetLastError(
   2627             VE_INVALID_OPERATION, kTraceWarning,
   2628             "DeRegisterRxVadObserver() observer already disabled");
   2629         return 0;
   2630     }
   2631     _rxVadObserverPtr = NULL;
   2632     _RxVadDetection = false;
   2633     return 0;
   2634 }
   2635 
   2636 int
   2637 Channel::VoiceActivityIndicator(int &activity)
   2638 {
   2639     activity = _sendFrameType;
   2640     return 0;
   2641 }
   2642 
   2643 #ifdef WEBRTC_VOICE_ENGINE_AGC
   2644 
   2645 int
   2646 Channel::SetRxAgcStatus(bool enable, AgcModes mode)
   2647 {
   2648     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2649                  "Channel::SetRxAgcStatus(enable=%d, mode=%d)",
   2650                  (int)enable, (int)mode);
   2651 
   2652     GainControl::Mode agcMode = kDefaultRxAgcMode;
   2653     switch (mode)
   2654     {
   2655         case kAgcDefault:
   2656             break;
   2657         case kAgcUnchanged:
   2658             agcMode = rx_audioproc_->gain_control()->mode();
   2659             break;
   2660         case kAgcFixedDigital:
   2661             agcMode = GainControl::kFixedDigital;
   2662             break;
   2663         case kAgcAdaptiveDigital:
   2664             agcMode =GainControl::kAdaptiveDigital;
   2665             break;
   2666         default:
   2667             _engineStatisticsPtr->SetLastError(
   2668                 VE_INVALID_ARGUMENT, kTraceError,
   2669                 "SetRxAgcStatus() invalid Agc mode");
   2670             return -1;
   2671     }
   2672 
   2673     if (rx_audioproc_->gain_control()->set_mode(agcMode) != 0)
   2674     {
   2675         _engineStatisticsPtr->SetLastError(
   2676             VE_APM_ERROR, kTraceError,
   2677             "SetRxAgcStatus() failed to set Agc mode");
   2678         return -1;
   2679     }
   2680     if (rx_audioproc_->gain_control()->Enable(enable) != 0)
   2681     {
   2682         _engineStatisticsPtr->SetLastError(
   2683             VE_APM_ERROR, kTraceError,
   2684             "SetRxAgcStatus() failed to set Agc state");
   2685         return -1;
   2686     }
   2687 
   2688     _rxAgcIsEnabled = enable;
   2689     channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled);
   2690 
   2691     return 0;
   2692 }
   2693 
   2694 int
   2695 Channel::GetRxAgcStatus(bool& enabled, AgcModes& mode)
   2696 {
   2697     bool enable = rx_audioproc_->gain_control()->is_enabled();
   2698     GainControl::Mode agcMode =
   2699         rx_audioproc_->gain_control()->mode();
   2700 
   2701     enabled = enable;
   2702 
   2703     switch (agcMode)
   2704     {
   2705         case GainControl::kFixedDigital:
   2706             mode = kAgcFixedDigital;
   2707             break;
   2708         case GainControl::kAdaptiveDigital:
   2709             mode = kAgcAdaptiveDigital;
   2710             break;
   2711         default:
   2712             _engineStatisticsPtr->SetLastError(
   2713                 VE_APM_ERROR, kTraceError,
   2714                 "GetRxAgcStatus() invalid Agc mode");
   2715             return -1;
   2716     }
   2717 
   2718     return 0;
   2719 }
   2720 
   2721 int
   2722 Channel::SetRxAgcConfig(AgcConfig config)
   2723 {
   2724     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2725                  "Channel::SetRxAgcConfig()");
   2726 
   2727     if (rx_audioproc_->gain_control()->set_target_level_dbfs(
   2728         config.targetLeveldBOv) != 0)
   2729     {
   2730         _engineStatisticsPtr->SetLastError(
   2731             VE_APM_ERROR, kTraceError,
   2732             "SetRxAgcConfig() failed to set target peak |level|"
   2733             "(or envelope) of the Agc");
   2734         return -1;
   2735     }
   2736     if (rx_audioproc_->gain_control()->set_compression_gain_db(
   2737         config.digitalCompressionGaindB) != 0)
   2738     {
   2739         _engineStatisticsPtr->SetLastError(
   2740             VE_APM_ERROR, kTraceError,
   2741             "SetRxAgcConfig() failed to set the range in |gain| the"
   2742             " digital compression stage may apply");
   2743         return -1;
   2744     }
   2745     if (rx_audioproc_->gain_control()->enable_limiter(
   2746         config.limiterEnable) != 0)
   2747     {
   2748         _engineStatisticsPtr->SetLastError(
   2749             VE_APM_ERROR, kTraceError,
   2750             "SetRxAgcConfig() failed to set hard limiter to the signal");
   2751         return -1;
   2752     }
   2753 
   2754     return 0;
   2755 }
   2756 
   2757 int
   2758 Channel::GetRxAgcConfig(AgcConfig& config)
   2759 {
   2760     config.targetLeveldBOv =
   2761         rx_audioproc_->gain_control()->target_level_dbfs();
   2762     config.digitalCompressionGaindB =
   2763         rx_audioproc_->gain_control()->compression_gain_db();
   2764     config.limiterEnable =
   2765         rx_audioproc_->gain_control()->is_limiter_enabled();
   2766 
   2767     return 0;
   2768 }
   2769 
   2770 #endif // #ifdef WEBRTC_VOICE_ENGINE_AGC
   2771 
   2772 #ifdef WEBRTC_VOICE_ENGINE_NR
   2773 
   2774 int
   2775 Channel::SetRxNsStatus(bool enable, NsModes mode)
   2776 {
   2777     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   2778                  "Channel::SetRxNsStatus(enable=%d, mode=%d)",
   2779                  (int)enable, (int)mode);
   2780 
   2781     NoiseSuppression::Level nsLevel = kDefaultNsMode;
   2782     switch (mode)
   2783     {
   2784 
   2785         case kNsDefault:
   2786             break;
   2787         case kNsUnchanged:
   2788             nsLevel = rx_audioproc_->noise_suppression()->level();
   2789             break;
   2790         case kNsConference:
   2791             nsLevel = NoiseSuppression::kHigh;
   2792             break;
   2793         case kNsLowSuppression:
   2794             nsLevel = NoiseSuppression::kLow;
   2795             break;
   2796         case kNsModerateSuppression:
   2797             nsLevel = NoiseSuppression::kModerate;
   2798             break;
   2799         case kNsHighSuppression:
   2800             nsLevel = NoiseSuppression::kHigh;
   2801             break;
   2802         case kNsVeryHighSuppression:
   2803             nsLevel = NoiseSuppression::kVeryHigh;
   2804             break;
   2805     }
   2806 
   2807     if (rx_audioproc_->noise_suppression()->set_level(nsLevel)
   2808         != 0)
   2809     {
   2810         _engineStatisticsPtr->SetLastError(
   2811             VE_APM_ERROR, kTraceError,
   2812             "SetRxNsStatus() failed to set NS level");
   2813         return -1;
   2814     }
   2815     if (rx_audioproc_->noise_suppression()->Enable(enable) != 0)
   2816     {
   2817         _engineStatisticsPtr->SetLastError(
   2818             VE_APM_ERROR, kTraceError,
   2819             "SetRxNsStatus() failed to set NS state");
   2820         return -1;
   2821     }
   2822 
   2823     _rxNsIsEnabled = enable;
   2824     channel_state_.SetRxApmIsEnabled(_rxAgcIsEnabled || _rxNsIsEnabled);
   2825 
   2826     return 0;
   2827 }
   2828 
   2829 int
   2830 Channel::GetRxNsStatus(bool& enabled, NsModes& mode)
   2831 {
   2832     bool enable =
   2833         rx_audioproc_->noise_suppression()->is_enabled();
   2834     NoiseSuppression::Level ncLevel =
   2835         rx_audioproc_->noise_suppression()->level();
   2836 
   2837     enabled = enable;
   2838 
   2839     switch (ncLevel)
   2840     {
   2841         case NoiseSuppression::kLow:
   2842             mode = kNsLowSuppression;
   2843             break;
   2844         case NoiseSuppression::kModerate:
   2845             mode = kNsModerateSuppression;
   2846             break;
   2847         case NoiseSuppression::kHigh:
   2848             mode = kNsHighSuppression;
   2849             break;
   2850         case NoiseSuppression::kVeryHigh:
   2851             mode = kNsVeryHighSuppression;
   2852             break;
   2853     }
   2854 
   2855     return 0;
   2856 }
   2857 
   2858 #endif // #ifdef WEBRTC_VOICE_ENGINE_NR
   2859 
   2860 int
   2861 Channel::SetLocalSSRC(unsigned int ssrc)
   2862 {
   2863     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   2864                  "Channel::SetLocalSSRC()");
   2865     if (channel_state_.Get().sending)
   2866     {
   2867         _engineStatisticsPtr->SetLastError(
   2868             VE_ALREADY_SENDING, kTraceError,
   2869             "SetLocalSSRC() already sending");
   2870         return -1;
   2871     }
   2872     _rtpRtcpModule->SetSSRC(ssrc);
   2873     return 0;
   2874 }
   2875 
   2876 int
   2877 Channel::GetLocalSSRC(unsigned int& ssrc)
   2878 {
   2879     ssrc = _rtpRtcpModule->SSRC();
   2880     return 0;
   2881 }
   2882 
   2883 int
   2884 Channel::GetRemoteSSRC(unsigned int& ssrc)
   2885 {
   2886     ssrc = rtp_receiver_->SSRC();
   2887     return 0;
   2888 }
   2889 
   2890 int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) {
   2891   _includeAudioLevelIndication = enable;
   2892   return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id);
   2893 }
   2894 
   2895 int Channel::SetReceiveAudioLevelIndicationStatus(bool enable,
   2896                                                   unsigned char id) {
   2897   rtp_header_parser_->DeregisterRtpHeaderExtension(
   2898       kRtpExtensionAudioLevel);
   2899   if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension(
   2900           kRtpExtensionAudioLevel, id)) {
   2901     return -1;
   2902   }
   2903   return 0;
   2904 }
   2905 
   2906 int Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) {
   2907   return SetSendRtpHeaderExtension(enable, kRtpExtensionAbsoluteSendTime, id);
   2908 }
   2909 
   2910 int Channel::SetReceiveAbsoluteSenderTimeStatus(bool enable, unsigned char id) {
   2911   rtp_header_parser_->DeregisterRtpHeaderExtension(
   2912       kRtpExtensionAbsoluteSendTime);
   2913   if (enable && !rtp_header_parser_->RegisterRtpHeaderExtension(
   2914       kRtpExtensionAbsoluteSendTime, id)) {
   2915     return -1;
   2916   }
   2917   return 0;
   2918 }
   2919 
   2920 void Channel::EnableSendTransportSequenceNumber(int id) {
   2921   int ret =
   2922       SetSendRtpHeaderExtension(true, kRtpExtensionTransportSequenceNumber, id);
   2923   RTC_DCHECK_EQ(0, ret);
   2924 }
   2925 
   2926 void Channel::SetCongestionControlObjects(
   2927     RtpPacketSender* rtp_packet_sender,
   2928     TransportFeedbackObserver* transport_feedback_observer,
   2929     PacketRouter* packet_router) {
   2930   RTC_DCHECK(packet_router != nullptr || packet_router_ != nullptr);
   2931   if (transport_feedback_observer) {
   2932     RTC_DCHECK(feedback_observer_proxy_.get());
   2933     feedback_observer_proxy_->SetTransportFeedbackObserver(
   2934         transport_feedback_observer);
   2935   }
   2936   if (rtp_packet_sender) {
   2937     RTC_DCHECK(rtp_packet_sender_proxy_.get());
   2938     rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
   2939   }
   2940   if (seq_num_allocator_proxy_.get()) {
   2941     seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
   2942   }
   2943   _rtpRtcpModule->SetStorePacketsStatus(rtp_packet_sender != nullptr, 600);
   2944   if (packet_router != nullptr) {
   2945     packet_router->AddRtpModule(_rtpRtcpModule.get());
   2946   } else {
   2947     packet_router_->RemoveRtpModule(_rtpRtcpModule.get());
   2948   }
   2949   packet_router_ = packet_router;
   2950 }
   2951 
   2952 void Channel::SetRTCPStatus(bool enable) {
   2953   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   2954                "Channel::SetRTCPStatus()");
   2955   _rtpRtcpModule->SetRTCPStatus(enable ? RtcpMode::kCompound : RtcpMode::kOff);
   2956 }
   2957 
   2958 int
   2959 Channel::GetRTCPStatus(bool& enabled)
   2960 {
   2961   RtcpMode method = _rtpRtcpModule->RTCP();
   2962   enabled = (method != RtcpMode::kOff);
   2963     return 0;
   2964 }
   2965 
   2966 int
   2967 Channel::SetRTCP_CNAME(const char cName[256])
   2968 {
   2969     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   2970                  "Channel::SetRTCP_CNAME()");
   2971     if (_rtpRtcpModule->SetCNAME(cName) != 0)
   2972     {
   2973         _engineStatisticsPtr->SetLastError(
   2974             VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   2975             "SetRTCP_CNAME() failed to set RTCP CNAME");
   2976         return -1;
   2977     }
   2978     return 0;
   2979 }
   2980 
   2981 int
   2982 Channel::GetRemoteRTCP_CNAME(char cName[256])
   2983 {
   2984     if (cName == NULL)
   2985     {
   2986         _engineStatisticsPtr->SetLastError(
   2987             VE_INVALID_ARGUMENT, kTraceError,
   2988             "GetRemoteRTCP_CNAME() invalid CNAME input buffer");
   2989         return -1;
   2990     }
   2991     char cname[RTCP_CNAME_SIZE];
   2992     const uint32_t remoteSSRC = rtp_receiver_->SSRC();
   2993     if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0)
   2994     {
   2995         _engineStatisticsPtr->SetLastError(
   2996             VE_CANNOT_RETRIEVE_CNAME, kTraceError,
   2997             "GetRemoteRTCP_CNAME() failed to retrieve remote RTCP CNAME");
   2998         return -1;
   2999     }
   3000     strcpy(cName, cname);
   3001     return 0;
   3002 }
   3003 
   3004 int
   3005 Channel::GetRemoteRTCPData(
   3006     unsigned int& NTPHigh,
   3007     unsigned int& NTPLow,
   3008     unsigned int& timestamp,
   3009     unsigned int& playoutTimestamp,
   3010     unsigned int* jitter,
   3011     unsigned short* fractionLost)
   3012 {
   3013     // --- Information from sender info in received Sender Reports
   3014 
   3015     RTCPSenderInfo senderInfo;
   3016     if (_rtpRtcpModule->RemoteRTCPStat(&senderInfo) != 0)
   3017     {
   3018         _engineStatisticsPtr->SetLastError(
   3019             VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   3020             "GetRemoteRTCPData() failed to retrieve sender info for remote "
   3021             "side");
   3022         return -1;
   3023     }
   3024 
   3025     // We only utilize 12 out of 20 bytes in the sender info (ignores packet
   3026     // and octet count)
   3027     NTPHigh = senderInfo.NTPseconds;
   3028     NTPLow = senderInfo.NTPfraction;
   3029     timestamp = senderInfo.RTPtimeStamp;
   3030 
   3031     // --- Locally derived information
   3032 
   3033     // This value is updated on each incoming RTCP packet (0 when no packet
   3034     // has been received)
   3035     playoutTimestamp = playout_timestamp_rtcp_;
   3036 
   3037     if (NULL != jitter || NULL != fractionLost)
   3038     {
   3039         // Get all RTCP receiver report blocks that have been received on this
   3040         // channel. If we receive RTP packets from a remote source we know the
   3041         // remote SSRC and use the report block from him.
   3042         // Otherwise use the first report block.
   3043         std::vector<RTCPReportBlock> remote_stats;
   3044         if (_rtpRtcpModule->RemoteRTCPStat(&remote_stats) != 0 ||
   3045             remote_stats.empty()) {
   3046           WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3047                        VoEId(_instanceId, _channelId),
   3048                        "GetRemoteRTCPData() failed to measure statistics due"
   3049                        " to lack of received RTP and/or RTCP packets");
   3050           return -1;
   3051         }
   3052 
   3053         uint32_t remoteSSRC = rtp_receiver_->SSRC();
   3054         std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin();
   3055         for (; it != remote_stats.end(); ++it) {
   3056           if (it->remoteSSRC == remoteSSRC)
   3057             break;
   3058         }
   3059 
   3060         if (it == remote_stats.end()) {
   3061           // If we have not received any RTCP packets from this SSRC it probably
   3062           // means that we have not received any RTP packets.
   3063           // Use the first received report block instead.
   3064           it = remote_stats.begin();
   3065           remoteSSRC = it->remoteSSRC;
   3066         }
   3067 
   3068         if (jitter) {
   3069           *jitter = it->jitter;
   3070         }
   3071 
   3072         if (fractionLost) {
   3073           *fractionLost = it->fractionLost;
   3074         }
   3075     }
   3076     return 0;
   3077 }
   3078 
   3079 int
   3080 Channel::SendApplicationDefinedRTCPPacket(unsigned char subType,
   3081                                              unsigned int name,
   3082                                              const char* data,
   3083                                              unsigned short dataLengthInBytes)
   3084 {
   3085     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   3086                  "Channel::SendApplicationDefinedRTCPPacket()");
   3087     if (!channel_state_.Get().sending)
   3088     {
   3089         _engineStatisticsPtr->SetLastError(
   3090             VE_NOT_SENDING, kTraceError,
   3091             "SendApplicationDefinedRTCPPacket() not sending");
   3092         return -1;
   3093     }
   3094     if (NULL == data)
   3095     {
   3096         _engineStatisticsPtr->SetLastError(
   3097             VE_INVALID_ARGUMENT, kTraceError,
   3098             "SendApplicationDefinedRTCPPacket() invalid data value");
   3099         return -1;
   3100     }
   3101     if (dataLengthInBytes % 4 != 0)
   3102     {
   3103         _engineStatisticsPtr->SetLastError(
   3104             VE_INVALID_ARGUMENT, kTraceError,
   3105             "SendApplicationDefinedRTCPPacket() invalid length value");
   3106         return -1;
   3107     }
   3108     RtcpMode status = _rtpRtcpModule->RTCP();
   3109     if (status == RtcpMode::kOff) {
   3110         _engineStatisticsPtr->SetLastError(
   3111             VE_RTCP_ERROR, kTraceError,
   3112             "SendApplicationDefinedRTCPPacket() RTCP is disabled");
   3113         return -1;
   3114     }
   3115 
   3116     // Create and schedule the RTCP APP packet for transmission
   3117     if (_rtpRtcpModule->SetRTCPApplicationSpecificData(
   3118         subType,
   3119         name,
   3120         (const unsigned char*) data,
   3121         dataLengthInBytes) != 0)
   3122     {
   3123         _engineStatisticsPtr->SetLastError(
   3124             VE_SEND_ERROR, kTraceError,
   3125             "SendApplicationDefinedRTCPPacket() failed to send RTCP packet");
   3126         return -1;
   3127     }
   3128     return 0;
   3129 }
   3130 
   3131 int
   3132 Channel::GetRTPStatistics(
   3133         unsigned int& averageJitterMs,
   3134         unsigned int& maxJitterMs,
   3135         unsigned int& discardedPackets)
   3136 {
   3137     // The jitter statistics is updated for each received RTP packet and is
   3138     // based on received packets.
   3139     if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) {
   3140       // If RTCP is off, there is no timed thread in the RTCP module regularly
   3141       // generating new stats, trigger the update manually here instead.
   3142       StreamStatistician* statistician =
   3143           rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
   3144       if (statistician) {
   3145         // Don't use returned statistics, use data from proxy instead so that
   3146         // max jitter can be fetched atomically.
   3147         RtcpStatistics s;
   3148         statistician->GetStatistics(&s, true);
   3149       }
   3150     }
   3151 
   3152     ChannelStatistics stats = statistics_proxy_->GetStats();
   3153     const int32_t playoutFrequency = audio_coding_->PlayoutFrequency();
   3154     if (playoutFrequency > 0) {
   3155       // Scale RTP statistics given the current playout frequency
   3156       maxJitterMs = stats.max_jitter / (playoutFrequency / 1000);
   3157       averageJitterMs = stats.rtcp.jitter / (playoutFrequency / 1000);
   3158     }
   3159 
   3160     discardedPackets = _numberOfDiscardedPackets;
   3161 
   3162     return 0;
   3163 }
   3164 
   3165 int Channel::GetRemoteRTCPReportBlocks(
   3166     std::vector<ReportBlock>* report_blocks) {
   3167   if (report_blocks == NULL) {
   3168     _engineStatisticsPtr->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
   3169       "GetRemoteRTCPReportBlock()s invalid report_blocks.");
   3170     return -1;
   3171   }
   3172 
   3173   // Get the report blocks from the latest received RTCP Sender or Receiver
   3174   // Report. Each element in the vector contains the sender's SSRC and a
   3175   // report block according to RFC 3550.
   3176   std::vector<RTCPReportBlock> rtcp_report_blocks;
   3177   if (_rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks) != 0) {
   3178     return -1;
   3179   }
   3180 
   3181   if (rtcp_report_blocks.empty())
   3182     return 0;
   3183 
   3184   std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin();
   3185   for (; it != rtcp_report_blocks.end(); ++it) {
   3186     ReportBlock report_block;
   3187     report_block.sender_SSRC = it->remoteSSRC;
   3188     report_block.source_SSRC = it->sourceSSRC;
   3189     report_block.fraction_lost = it->fractionLost;
   3190     report_block.cumulative_num_packets_lost = it->cumulativeLost;
   3191     report_block.extended_highest_sequence_number = it->extendedHighSeqNum;
   3192     report_block.interarrival_jitter = it->jitter;
   3193     report_block.last_SR_timestamp = it->lastSR;
   3194     report_block.delay_since_last_SR = it->delaySinceLastSR;
   3195     report_blocks->push_back(report_block);
   3196   }
   3197   return 0;
   3198 }
   3199 
   3200 int
   3201 Channel::GetRTPStatistics(CallStatistics& stats)
   3202 {
   3203     // --- RtcpStatistics
   3204 
   3205     // The jitter statistics is updated for each received RTP packet and is
   3206     // based on received packets.
   3207     RtcpStatistics statistics;
   3208     StreamStatistician* statistician =
   3209         rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
   3210     if (!statistician ||
   3211         !statistician->GetStatistics(
   3212             &statistics, _rtpRtcpModule->RTCP() == RtcpMode::kOff)) {
   3213       _engineStatisticsPtr->SetLastError(
   3214           VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
   3215           "GetRTPStatistics() failed to read RTP statistics from the "
   3216           "RTP/RTCP module");
   3217     }
   3218 
   3219     stats.fractionLost = statistics.fraction_lost;
   3220     stats.cumulativeLost = statistics.cumulative_lost;
   3221     stats.extendedMax = statistics.extended_max_sequence_number;
   3222     stats.jitterSamples = statistics.jitter;
   3223 
   3224     // --- RTT
   3225     stats.rttMs = GetRTT(true);
   3226 
   3227     // --- Data counters
   3228 
   3229     size_t bytesSent(0);
   3230     uint32_t packetsSent(0);
   3231     size_t bytesReceived(0);
   3232     uint32_t packetsReceived(0);
   3233 
   3234     if (statistician) {
   3235       statistician->GetDataCounters(&bytesReceived, &packetsReceived);
   3236     }
   3237 
   3238     if (_rtpRtcpModule->DataCountersRTP(&bytesSent,
   3239                                         &packetsSent) != 0)
   3240     {
   3241         WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3242                      VoEId(_instanceId, _channelId),
   3243                      "GetRTPStatistics() failed to retrieve RTP datacounters =>"
   3244                      " output will not be complete");
   3245     }
   3246 
   3247     stats.bytesSent = bytesSent;
   3248     stats.packetsSent = packetsSent;
   3249     stats.bytesReceived = bytesReceived;
   3250     stats.packetsReceived = packetsReceived;
   3251 
   3252     // --- Timestamps
   3253     {
   3254       CriticalSectionScoped lock(ts_stats_lock_.get());
   3255       stats.capture_start_ntp_time_ms_ = capture_start_ntp_time_ms_;
   3256     }
   3257     return 0;
   3258 }
   3259 
   3260 int Channel::SetREDStatus(bool enable, int redPayloadtype) {
   3261   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   3262                "Channel::SetREDStatus()");
   3263 
   3264   if (enable) {
   3265     if (redPayloadtype < 0 || redPayloadtype > 127) {
   3266       _engineStatisticsPtr->SetLastError(
   3267           VE_PLTYPE_ERROR, kTraceError,
   3268           "SetREDStatus() invalid RED payload type");
   3269       return -1;
   3270     }
   3271 
   3272     if (SetRedPayloadType(redPayloadtype) < 0) {
   3273       _engineStatisticsPtr->SetLastError(
   3274           VE_CODEC_ERROR, kTraceError,
   3275           "SetSecondarySendCodec() Failed to register RED ACM");
   3276       return -1;
   3277     }
   3278   }
   3279 
   3280   if (audio_coding_->SetREDStatus(enable) != 0) {
   3281     _engineStatisticsPtr->SetLastError(
   3282         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   3283         "SetREDStatus() failed to set RED state in the ACM");
   3284     return -1;
   3285   }
   3286   return 0;
   3287 }
   3288 
   3289 int
   3290 Channel::GetREDStatus(bool& enabled, int& redPayloadtype)
   3291 {
   3292     enabled = audio_coding_->REDStatus();
   3293     if (enabled)
   3294     {
   3295       int8_t payloadType = 0;
   3296       if (_rtpRtcpModule->SendREDPayloadType(&payloadType) != 0) {
   3297             _engineStatisticsPtr->SetLastError(
   3298                 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   3299                 "GetREDStatus() failed to retrieve RED PT from RTP/RTCP "
   3300                 "module");
   3301             return -1;
   3302         }
   3303         redPayloadtype = payloadType;
   3304         return 0;
   3305     }
   3306     return 0;
   3307 }
   3308 
   3309 int Channel::SetCodecFECStatus(bool enable) {
   3310   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   3311                "Channel::SetCodecFECStatus()");
   3312 
   3313   if (audio_coding_->SetCodecFEC(enable) != 0) {
   3314     _engineStatisticsPtr->SetLastError(
   3315         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   3316         "SetCodecFECStatus() failed to set FEC state");
   3317     return -1;
   3318   }
   3319   return 0;
   3320 }
   3321 
   3322 bool Channel::GetCodecFECStatus() {
   3323   bool enabled = audio_coding_->CodecFEC();
   3324   return enabled;
   3325 }
   3326 
   3327 void Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) {
   3328   // None of these functions can fail.
   3329   // If pacing is enabled we always store packets.
   3330   if (!pacing_enabled_)
   3331     _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets);
   3332   rtp_receive_statistics_->SetMaxReorderingThreshold(maxNumberOfPackets);
   3333   rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff);
   3334   if (enable)
   3335     audio_coding_->EnableNack(maxNumberOfPackets);
   3336   else
   3337     audio_coding_->DisableNack();
   3338 }
   3339 
   3340 // Called when we are missing one or more packets.
   3341 int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) {
   3342   return _rtpRtcpModule->SendNACK(sequence_numbers, length);
   3343 }
   3344 
   3345 uint32_t
   3346 Channel::Demultiplex(const AudioFrame& audioFrame)
   3347 {
   3348     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   3349                  "Channel::Demultiplex()");
   3350     _audioFrame.CopyFrom(audioFrame);
   3351     _audioFrame.id_ = _channelId;
   3352     return 0;
   3353 }
   3354 
   3355 void Channel::Demultiplex(const int16_t* audio_data,
   3356                           int sample_rate,
   3357                           size_t number_of_frames,
   3358                           size_t number_of_channels) {
   3359   CodecInst codec;
   3360   GetSendCodec(codec);
   3361 
   3362   // Never upsample or upmix the capture signal here. This should be done at the
   3363   // end of the send chain.
   3364   _audioFrame.sample_rate_hz_ = std::min(codec.plfreq, sample_rate);
   3365   _audioFrame.num_channels_ = std::min(number_of_channels, codec.channels);
   3366   RemixAndResample(audio_data, number_of_frames, number_of_channels,
   3367                    sample_rate, &input_resampler_, &_audioFrame);
   3368 }
   3369 
   3370 uint32_t
   3371 Channel::PrepareEncodeAndSend(int mixingFrequency)
   3372 {
   3373     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   3374                  "Channel::PrepareEncodeAndSend()");
   3375 
   3376     if (_audioFrame.samples_per_channel_ == 0)
   3377     {
   3378         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
   3379                      "Channel::PrepareEncodeAndSend() invalid audio frame");
   3380         return 0xFFFFFFFF;
   3381     }
   3382 
   3383     if (channel_state_.Get().input_file_playing)
   3384     {
   3385         MixOrReplaceAudioWithFile(mixingFrequency);
   3386     }
   3387 
   3388     bool is_muted = Mute();  // Cache locally as Mute() takes a lock.
   3389     if (is_muted) {
   3390       AudioFrameOperations::Mute(_audioFrame);
   3391     }
   3392 
   3393     if (channel_state_.Get().input_external_media)
   3394     {
   3395         CriticalSectionScoped cs(&_callbackCritSect);
   3396         const bool isStereo = (_audioFrame.num_channels_ == 2);
   3397         if (_inputExternalMediaCallbackPtr)
   3398         {
   3399             _inputExternalMediaCallbackPtr->Process(
   3400                 _channelId,
   3401                 kRecordingPerChannel,
   3402                (int16_t*)_audioFrame.data_,
   3403                 _audioFrame.samples_per_channel_,
   3404                 _audioFrame.sample_rate_hz_,
   3405                 isStereo);
   3406         }
   3407     }
   3408 
   3409     InsertInbandDtmfTone();
   3410 
   3411     if (_includeAudioLevelIndication) {
   3412       size_t length =
   3413           _audioFrame.samples_per_channel_ * _audioFrame.num_channels_;
   3414       if (is_muted) {
   3415         rms_level_.ProcessMuted(length);
   3416       } else {
   3417         rms_level_.Process(_audioFrame.data_, length);
   3418       }
   3419     }
   3420 
   3421     return 0;
   3422 }
   3423 
   3424 uint32_t
   3425 Channel::EncodeAndSend()
   3426 {
   3427     WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   3428                  "Channel::EncodeAndSend()");
   3429 
   3430     assert(_audioFrame.num_channels_ <= 2);
   3431     if (_audioFrame.samples_per_channel_ == 0)
   3432     {
   3433         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
   3434                      "Channel::EncodeAndSend() invalid audio frame");
   3435         return 0xFFFFFFFF;
   3436     }
   3437 
   3438     _audioFrame.id_ = _channelId;
   3439 
   3440     // --- Add 10ms of raw (PCM) audio data to the encoder @ 32kHz.
   3441 
   3442     // The ACM resamples internally.
   3443     _audioFrame.timestamp_ = _timeStamp;
   3444     // This call will trigger AudioPacketizationCallback::SendData if encoding
   3445     // is done and payload is ready for packetization and transmission.
   3446     // Otherwise, it will return without invoking the callback.
   3447     if (audio_coding_->Add10MsData((AudioFrame&)_audioFrame) < 0)
   3448     {
   3449         WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
   3450                      "Channel::EncodeAndSend() ACM encoding failed");
   3451         return 0xFFFFFFFF;
   3452     }
   3453 
   3454     _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_);
   3455     return 0;
   3456 }
   3457 
   3458 void Channel::DisassociateSendChannel(int channel_id) {
   3459   CriticalSectionScoped lock(assoc_send_channel_lock_.get());
   3460   Channel* channel = associate_send_channel_.channel();
   3461   if (channel && channel->ChannelId() == channel_id) {
   3462     // If this channel is associated with a send channel of the specified
   3463     // Channel ID, disassociate with it.
   3464     ChannelOwner ref(NULL);
   3465     associate_send_channel_ = ref;
   3466   }
   3467 }
   3468 
   3469 int Channel::RegisterExternalMediaProcessing(
   3470     ProcessingTypes type,
   3471     VoEMediaProcess& processObject)
   3472 {
   3473     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   3474                  "Channel::RegisterExternalMediaProcessing()");
   3475 
   3476     CriticalSectionScoped cs(&_callbackCritSect);
   3477 
   3478     if (kPlaybackPerChannel == type)
   3479     {
   3480         if (_outputExternalMediaCallbackPtr)
   3481         {
   3482             _engineStatisticsPtr->SetLastError(
   3483                 VE_INVALID_OPERATION, kTraceError,
   3484                 "Channel::RegisterExternalMediaProcessing() "
   3485                 "output external media already enabled");
   3486             return -1;
   3487         }
   3488         _outputExternalMediaCallbackPtr = &processObject;
   3489         _outputExternalMedia = true;
   3490     }
   3491     else if (kRecordingPerChannel == type)
   3492     {
   3493         if (_inputExternalMediaCallbackPtr)
   3494         {
   3495             _engineStatisticsPtr->SetLastError(
   3496                 VE_INVALID_OPERATION, kTraceError,
   3497                 "Channel::RegisterExternalMediaProcessing() "
   3498                 "output external media already enabled");
   3499             return -1;
   3500         }
   3501         _inputExternalMediaCallbackPtr = &processObject;
   3502         channel_state_.SetInputExternalMedia(true);
   3503     }
   3504     return 0;
   3505 }
   3506 
   3507 int Channel::DeRegisterExternalMediaProcessing(ProcessingTypes type)
   3508 {
   3509     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   3510                  "Channel::DeRegisterExternalMediaProcessing()");
   3511 
   3512     CriticalSectionScoped cs(&_callbackCritSect);
   3513 
   3514     if (kPlaybackPerChannel == type)
   3515     {
   3516         if (!_outputExternalMediaCallbackPtr)
   3517         {
   3518             _engineStatisticsPtr->SetLastError(
   3519                 VE_INVALID_OPERATION, kTraceWarning,
   3520                 "Channel::DeRegisterExternalMediaProcessing() "
   3521                 "output external media already disabled");
   3522             return 0;
   3523         }
   3524         _outputExternalMedia = false;
   3525         _outputExternalMediaCallbackPtr = NULL;
   3526     }
   3527     else if (kRecordingPerChannel == type)
   3528     {
   3529         if (!_inputExternalMediaCallbackPtr)
   3530         {
   3531             _engineStatisticsPtr->SetLastError(
   3532                 VE_INVALID_OPERATION, kTraceWarning,
   3533                 "Channel::DeRegisterExternalMediaProcessing() "
   3534                 "input external media already disabled");
   3535             return 0;
   3536         }
   3537         channel_state_.SetInputExternalMedia(false);
   3538         _inputExternalMediaCallbackPtr = NULL;
   3539     }
   3540 
   3541     return 0;
   3542 }
   3543 
   3544 int Channel::SetExternalMixing(bool enabled) {
   3545     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   3546                  "Channel::SetExternalMixing(enabled=%d)", enabled);
   3547 
   3548     if (channel_state_.Get().playing)
   3549     {
   3550         _engineStatisticsPtr->SetLastError(
   3551             VE_INVALID_OPERATION, kTraceError,
   3552             "Channel::SetExternalMixing() "
   3553             "external mixing cannot be changed while playing.");
   3554         return -1;
   3555     }
   3556 
   3557     _externalMixing = enabled;
   3558 
   3559     return 0;
   3560 }
   3561 
   3562 int
   3563 Channel::GetNetworkStatistics(NetworkStatistics& stats)
   3564 {
   3565     return audio_coding_->GetNetworkStatistics(&stats);
   3566 }
   3567 
   3568 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
   3569   audio_coding_->GetDecodingCallStatistics(stats);
   3570 }
   3571 
   3572 bool Channel::GetDelayEstimate(int* jitter_buffer_delay_ms,
   3573                                int* playout_buffer_delay_ms) const {
   3574   CriticalSectionScoped cs(video_sync_lock_.get());
   3575   if (_average_jitter_buffer_delay_us == 0) {
   3576     return false;
   3577   }
   3578   *jitter_buffer_delay_ms = (_average_jitter_buffer_delay_us + 500) / 1000 +
   3579       _recPacketDelayMs;
   3580   *playout_buffer_delay_ms = playout_delay_ms_;
   3581   return true;
   3582 }
   3583 
   3584 uint32_t Channel::GetDelayEstimate() const {
   3585   int jitter_buffer_delay_ms = 0;
   3586   int playout_buffer_delay_ms = 0;
   3587   GetDelayEstimate(&jitter_buffer_delay_ms, &playout_buffer_delay_ms);
   3588   return jitter_buffer_delay_ms + playout_buffer_delay_ms;
   3589 }
   3590 
   3591 int Channel::LeastRequiredDelayMs() const {
   3592   return audio_coding_->LeastRequiredDelayMs();
   3593 }
   3594 
   3595 int
   3596 Channel::SetMinimumPlayoutDelay(int delayMs)
   3597 {
   3598     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   3599                  "Channel::SetMinimumPlayoutDelay()");
   3600     if ((delayMs < kVoiceEngineMinMinPlayoutDelayMs) ||
   3601         (delayMs > kVoiceEngineMaxMinPlayoutDelayMs))
   3602     {
   3603         _engineStatisticsPtr->SetLastError(
   3604             VE_INVALID_ARGUMENT, kTraceError,
   3605             "SetMinimumPlayoutDelay() invalid min delay");
   3606         return -1;
   3607     }
   3608     if (audio_coding_->SetMinimumPlayoutDelay(delayMs) != 0)
   3609     {
   3610         _engineStatisticsPtr->SetLastError(
   3611             VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   3612             "SetMinimumPlayoutDelay() failed to set min playout delay");
   3613         return -1;
   3614     }
   3615     return 0;
   3616 }
   3617 
   3618 int Channel::GetPlayoutTimestamp(unsigned int& timestamp) {
   3619   uint32_t playout_timestamp_rtp = 0;
   3620   {
   3621     CriticalSectionScoped cs(video_sync_lock_.get());
   3622     playout_timestamp_rtp = playout_timestamp_rtp_;
   3623   }
   3624   if (playout_timestamp_rtp == 0)  {
   3625     _engineStatisticsPtr->SetLastError(
   3626         VE_CANNOT_RETRIEVE_VALUE, kTraceError,
   3627         "GetPlayoutTimestamp() failed to retrieve timestamp");
   3628     return -1;
   3629   }
   3630   timestamp = playout_timestamp_rtp;
   3631   return 0;
   3632 }
   3633 
   3634 int Channel::SetInitTimestamp(unsigned int timestamp) {
   3635   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   3636                "Channel::SetInitTimestamp()");
   3637   if (channel_state_.Get().sending) {
   3638     _engineStatisticsPtr->SetLastError(VE_SENDING, kTraceError,
   3639                                        "SetInitTimestamp() already sending");
   3640     return -1;
   3641   }
   3642   _rtpRtcpModule->SetStartTimestamp(timestamp);
   3643   return 0;
   3644 }
   3645 
   3646 int Channel::SetInitSequenceNumber(short sequenceNumber) {
   3647   WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
   3648                "Channel::SetInitSequenceNumber()");
   3649   if (channel_state_.Get().sending) {
   3650     _engineStatisticsPtr->SetLastError(
   3651         VE_SENDING, kTraceError, "SetInitSequenceNumber() already sending");
   3652     return -1;
   3653   }
   3654   _rtpRtcpModule->SetSequenceNumber(sequenceNumber);
   3655   return 0;
   3656 }
   3657 
   3658 int
   3659 Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const
   3660 {
   3661     *rtpRtcpModule = _rtpRtcpModule.get();
   3662     *rtp_receiver = rtp_receiver_.get();
   3663     return 0;
   3664 }
   3665 
   3666 // TODO(andrew): refactor Mix functions here and in transmit_mixer.cc to use
   3667 // a shared helper.
   3668 int32_t
   3669 Channel::MixOrReplaceAudioWithFile(int mixingFrequency)
   3670 {
   3671   rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[640]);
   3672     size_t fileSamples(0);
   3673 
   3674     {
   3675         CriticalSectionScoped cs(&_fileCritSect);
   3676 
   3677         if (_inputFilePlayerPtr == NULL)
   3678         {
   3679             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3680                          VoEId(_instanceId, _channelId),
   3681                          "Channel::MixOrReplaceAudioWithFile() fileplayer"
   3682                              " doesnt exist");
   3683             return -1;
   3684         }
   3685 
   3686         if (_inputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(),
   3687                                                       fileSamples,
   3688                                                       mixingFrequency) == -1)
   3689         {
   3690             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3691                          VoEId(_instanceId, _channelId),
   3692                          "Channel::MixOrReplaceAudioWithFile() file mixing "
   3693                          "failed");
   3694             return -1;
   3695         }
   3696         if (fileSamples == 0)
   3697         {
   3698             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3699                          VoEId(_instanceId, _channelId),
   3700                          "Channel::MixOrReplaceAudioWithFile() file is ended");
   3701             return 0;
   3702         }
   3703     }
   3704 
   3705     assert(_audioFrame.samples_per_channel_ == fileSamples);
   3706 
   3707     if (_mixFileWithMicrophone)
   3708     {
   3709         // Currently file stream is always mono.
   3710         // TODO(xians): Change the code when FilePlayer supports real stereo.
   3711         MixWithSat(_audioFrame.data_,
   3712                    _audioFrame.num_channels_,
   3713                    fileBuffer.get(),
   3714                    1,
   3715                    fileSamples);
   3716     }
   3717     else
   3718     {
   3719         // Replace ACM audio with file.
   3720         // Currently file stream is always mono.
   3721         // TODO(xians): Change the code when FilePlayer supports real stereo.
   3722         _audioFrame.UpdateFrame(_channelId,
   3723                                 0xFFFFFFFF,
   3724                                 fileBuffer.get(),
   3725                                 fileSamples,
   3726                                 mixingFrequency,
   3727                                 AudioFrame::kNormalSpeech,
   3728                                 AudioFrame::kVadUnknown,
   3729                                 1);
   3730 
   3731     }
   3732     return 0;
   3733 }
   3734 
   3735 int32_t
   3736 Channel::MixAudioWithFile(AudioFrame& audioFrame,
   3737                           int mixingFrequency)
   3738 {
   3739     assert(mixingFrequency <= 48000);
   3740 
   3741     rtc::scoped_ptr<int16_t[]> fileBuffer(new int16_t[960]);
   3742     size_t fileSamples(0);
   3743 
   3744     {
   3745         CriticalSectionScoped cs(&_fileCritSect);
   3746 
   3747         if (_outputFilePlayerPtr == NULL)
   3748         {
   3749             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3750                          VoEId(_instanceId, _channelId),
   3751                          "Channel::MixAudioWithFile() file mixing failed");
   3752             return -1;
   3753         }
   3754 
   3755         // We should get the frequency we ask for.
   3756         if (_outputFilePlayerPtr->Get10msAudioFromFile(fileBuffer.get(),
   3757                                                        fileSamples,
   3758                                                        mixingFrequency) == -1)
   3759         {
   3760             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3761                          VoEId(_instanceId, _channelId),
   3762                          "Channel::MixAudioWithFile() file mixing failed");
   3763             return -1;
   3764         }
   3765     }
   3766 
   3767     if (audioFrame.samples_per_channel_ == fileSamples)
   3768     {
   3769         // Currently file stream is always mono.
   3770         // TODO(xians): Change the code when FilePlayer supports real stereo.
   3771         MixWithSat(audioFrame.data_,
   3772                    audioFrame.num_channels_,
   3773                    fileBuffer.get(),
   3774                    1,
   3775                    fileSamples);
   3776     }
   3777     else
   3778     {
   3779         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
   3780             "Channel::MixAudioWithFile() samples_per_channel_(%" PRIuS ") != "
   3781             "fileSamples(%" PRIuS ")",
   3782             audioFrame.samples_per_channel_, fileSamples);
   3783         return -1;
   3784     }
   3785 
   3786     return 0;
   3787 }
   3788 
   3789 int
   3790 Channel::InsertInbandDtmfTone()
   3791 {
   3792     // Check if we should start a new tone.
   3793     if (_inbandDtmfQueue.PendingDtmf() &&
   3794         !_inbandDtmfGenerator.IsAddingTone() &&
   3795         _inbandDtmfGenerator.DelaySinceLastTone() >
   3796         kMinTelephoneEventSeparationMs)
   3797     {
   3798         int8_t eventCode(0);
   3799         uint16_t lengthMs(0);
   3800         uint8_t attenuationDb(0);
   3801 
   3802         eventCode = _inbandDtmfQueue.NextDtmf(&lengthMs, &attenuationDb);
   3803         _inbandDtmfGenerator.AddTone(eventCode, lengthMs, attenuationDb);
   3804         if (_playInbandDtmfEvent)
   3805         {
   3806             // Add tone to output mixer using a reduced length to minimize
   3807             // risk of echo.
   3808             _outputMixerPtr->PlayDtmfTone(eventCode, lengthMs - 80,
   3809                                           attenuationDb);
   3810         }
   3811     }
   3812 
   3813     if (_inbandDtmfGenerator.IsAddingTone())
   3814     {
   3815         uint16_t frequency(0);
   3816         _inbandDtmfGenerator.GetSampleRate(frequency);
   3817 
   3818         if (frequency != _audioFrame.sample_rate_hz_)
   3819         {
   3820             // Update sample rate of Dtmf tone since the mixing frequency
   3821             // has changed.
   3822             _inbandDtmfGenerator.SetSampleRate(
   3823                 (uint16_t) (_audioFrame.sample_rate_hz_));
   3824             // Reset the tone to be added taking the new sample rate into
   3825             // account.
   3826             _inbandDtmfGenerator.ResetTone();
   3827         }
   3828 
   3829         int16_t toneBuffer[320];
   3830         uint16_t toneSamples(0);
   3831         // Get 10ms tone segment and set time since last tone to zero
   3832         if (_inbandDtmfGenerator.Get10msTone(toneBuffer, toneSamples) == -1)
   3833         {
   3834             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
   3835                        VoEId(_instanceId, _channelId),
   3836                        "Channel::EncodeAndSend() inserting Dtmf failed");
   3837             return -1;
   3838         }
   3839 
   3840         // Replace mixed audio with DTMF tone.
   3841         for (size_t sample = 0;
   3842             sample < _audioFrame.samples_per_channel_;
   3843             sample++)
   3844         {
   3845             for (size_t channel = 0;
   3846                 channel < _audioFrame.num_channels_;
   3847                 channel++)
   3848             {
   3849                 const size_t index =
   3850                     sample * _audioFrame.num_channels_ + channel;
   3851                 _audioFrame.data_[index] = toneBuffer[sample];
   3852             }
   3853         }
   3854 
   3855         assert(_audioFrame.samples_per_channel_ == toneSamples);
   3856     } else
   3857     {
   3858         // Add 10ms to "delay-since-last-tone" counter
   3859         _inbandDtmfGenerator.UpdateDelaySinceLastTone();
   3860     }
   3861     return 0;
   3862 }
   3863 
   3864 void Channel::UpdatePlayoutTimestamp(bool rtcp) {
   3865   uint32_t playout_timestamp = 0;
   3866 
   3867   if (audio_coding_->PlayoutTimestamp(&playout_timestamp) == -1)  {
   3868     // This can happen if this channel has not been received any RTP packet. In
   3869     // this case, NetEq is not capable of computing playout timestamp.
   3870     return;
   3871   }
   3872 
   3873   uint16_t delay_ms = 0;
   3874   if (_audioDeviceModulePtr->PlayoutDelay(&delay_ms) == -1) {
   3875     WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
   3876                  "Channel::UpdatePlayoutTimestamp() failed to read playout"
   3877                  " delay from the ADM");
   3878     _engineStatisticsPtr->SetLastError(
   3879         VE_CANNOT_RETRIEVE_VALUE, kTraceError,
   3880         "UpdatePlayoutTimestamp() failed to retrieve playout delay");
   3881     return;
   3882   }
   3883 
   3884   jitter_buffer_playout_timestamp_ = playout_timestamp;
   3885 
   3886   // Remove the playout delay.
   3887   playout_timestamp -= (delay_ms * (GetPlayoutFrequency() / 1000));
   3888 
   3889   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   3890                "Channel::UpdatePlayoutTimestamp() => playoutTimestamp = %lu",
   3891                playout_timestamp);
   3892 
   3893   {
   3894     CriticalSectionScoped cs(video_sync_lock_.get());
   3895     if (rtcp) {
   3896       playout_timestamp_rtcp_ = playout_timestamp;
   3897     } else {
   3898       playout_timestamp_rtp_ = playout_timestamp;
   3899     }
   3900     playout_delay_ms_ = delay_ms;
   3901   }
   3902 }
   3903 
   3904 // Called for incoming RTP packets after successful RTP header parsing.
   3905 void Channel::UpdatePacketDelay(uint32_t rtp_timestamp,
   3906                                 uint16_t sequence_number) {
   3907   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
   3908                "Channel::UpdatePacketDelay(timestamp=%lu, sequenceNumber=%u)",
   3909                rtp_timestamp, sequence_number);
   3910 
   3911   // Get frequency of last received payload
   3912   int rtp_receive_frequency = GetPlayoutFrequency();
   3913 
   3914   // |jitter_buffer_playout_timestamp_| updated in UpdatePlayoutTimestamp for
   3915   // every incoming packet.
   3916   uint32_t timestamp_diff_ms = (rtp_timestamp -
   3917       jitter_buffer_playout_timestamp_) / (rtp_receive_frequency / 1000);
   3918   if (!IsNewerTimestamp(rtp_timestamp, jitter_buffer_playout_timestamp_) ||
   3919       timestamp_diff_ms > (2 * kVoiceEngineMaxMinPlayoutDelayMs)) {
   3920     // If |jitter_buffer_playout_timestamp_| is newer than the incoming RTP
   3921     // timestamp, the resulting difference is negative, but is set to zero.
   3922     // This can happen when a network glitch causes a packet to arrive late,
   3923     // and during long comfort noise periods with clock drift.
   3924     timestamp_diff_ms = 0;
   3925   }
   3926 
   3927   uint16_t packet_delay_ms = (rtp_timestamp - _previousTimestamp) /
   3928       (rtp_receive_frequency / 1000);
   3929 
   3930   _previousTimestamp = rtp_timestamp;
   3931 
   3932   if (timestamp_diff_ms == 0) return;
   3933 
   3934   {
   3935     CriticalSectionScoped cs(video_sync_lock_.get());
   3936 
   3937     if (packet_delay_ms >= 10 && packet_delay_ms <= 60) {
   3938       _recPacketDelayMs = packet_delay_ms;
   3939     }
   3940 
   3941     if (_average_jitter_buffer_delay_us == 0) {
   3942       _average_jitter_buffer_delay_us = timestamp_diff_ms * 1000;
   3943       return;
   3944     }
   3945 
   3946     // Filter average delay value using exponential filter (alpha is
   3947     // 7/8). We derive 1000 *_average_jitter_buffer_delay_us here (reduces
   3948     // risk of rounding error) and compensate for it in GetDelayEstimate()
   3949     // later.
   3950     _average_jitter_buffer_delay_us = (_average_jitter_buffer_delay_us * 7 +
   3951         1000 * timestamp_diff_ms + 500) / 8;
   3952   }
   3953 }
   3954 
   3955 void
   3956 Channel::RegisterReceiveCodecsToRTPModule()
   3957 {
   3958     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
   3959                  "Channel::RegisterReceiveCodecsToRTPModule()");
   3960 
   3961     CodecInst codec;
   3962     const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
   3963 
   3964     for (int idx = 0; idx < nSupportedCodecs; idx++)
   3965     {
   3966         // Open up the RTP/RTCP receiver for all supported codecs
   3967         if ((audio_coding_->Codec(idx, &codec) == -1) ||
   3968             (rtp_receiver_->RegisterReceivePayload(
   3969                 codec.plname,
   3970                 codec.pltype,
   3971                 codec.plfreq,
   3972                 codec.channels,
   3973                 (codec.rate < 0) ? 0 : codec.rate) == -1))
   3974         {
   3975             WEBRTC_TRACE(kTraceWarning,
   3976                          kTraceVoice,
   3977                          VoEId(_instanceId, _channelId),
   3978                          "Channel::RegisterReceiveCodecsToRTPModule() unable"
   3979                          " to register %s (%d/%d/%" PRIuS "/%d) to RTP/RTCP "
   3980                          "receiver",
   3981                          codec.plname, codec.pltype, codec.plfreq,
   3982                          codec.channels, codec.rate);
   3983         }
   3984         else
   3985         {
   3986             WEBRTC_TRACE(kTraceInfo,
   3987                          kTraceVoice,
   3988                          VoEId(_instanceId, _channelId),
   3989                          "Channel::RegisterReceiveCodecsToRTPModule() %s "
   3990                          "(%d/%d/%" PRIuS "/%d) has been added to the RTP/RTCP "
   3991                          "receiver",
   3992                          codec.plname, codec.pltype, codec.plfreq,
   3993                          codec.channels, codec.rate);
   3994         }
   3995     }
   3996 }
   3997 
   3998 // Assuming this method is called with valid payload type.
   3999 int Channel::SetRedPayloadType(int red_payload_type) {
   4000   CodecInst codec;
   4001   bool found_red = false;
   4002 
   4003   // Get default RED settings from the ACM database
   4004   const int num_codecs = AudioCodingModule::NumberOfCodecs();
   4005   for (int idx = 0; idx < num_codecs; idx++) {
   4006     audio_coding_->Codec(idx, &codec);
   4007     if (!STR_CASE_CMP(codec.plname, "RED")) {
   4008       found_red = true;
   4009       break;
   4010     }
   4011   }
   4012 
   4013   if (!found_red) {
   4014     _engineStatisticsPtr->SetLastError(
   4015         VE_CODEC_ERROR, kTraceError,
   4016         "SetRedPayloadType() RED is not supported");
   4017     return -1;
   4018   }
   4019 
   4020   codec.pltype = red_payload_type;
   4021   if (audio_coding_->RegisterSendCodec(codec) < 0) {
   4022     _engineStatisticsPtr->SetLastError(
   4023         VE_AUDIO_CODING_MODULE_ERROR, kTraceError,
   4024         "SetRedPayloadType() RED registration in ACM module failed");
   4025     return -1;
   4026   }
   4027 
   4028   if (_rtpRtcpModule->SetSendREDPayloadType(red_payload_type) != 0) {
   4029     _engineStatisticsPtr->SetLastError(
   4030         VE_RTP_RTCP_MODULE_ERROR, kTraceError,
   4031         "SetRedPayloadType() RED registration in RTP/RTCP module failed");
   4032     return -1;
   4033   }
   4034   return 0;
   4035 }
   4036 
   4037 int Channel::SetSendRtpHeaderExtension(bool enable, RTPExtensionType type,
   4038                                        unsigned char id) {
   4039   int error = 0;
   4040   _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type);
   4041   if (enable) {
   4042     error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(type, id);
   4043   }
   4044   return error;
   4045 }
   4046 
   4047 int32_t Channel::GetPlayoutFrequency() {
   4048   int32_t playout_frequency = audio_coding_->PlayoutFrequency();
   4049   CodecInst current_recive_codec;
   4050   if (audio_coding_->ReceiveCodec(&current_recive_codec) == 0) {
   4051     if (STR_CASE_CMP("G722", current_recive_codec.plname) == 0) {
   4052       // Even though the actual sampling rate for G.722 audio is
   4053       // 16,000 Hz, the RTP clock rate for the G722 payload format is
   4054       // 8,000 Hz because that value was erroneously assigned in
   4055       // RFC 1890 and must remain unchanged for backward compatibility.
   4056       playout_frequency = 8000;
   4057     } else if (STR_CASE_CMP("opus", current_recive_codec.plname) == 0) {
   4058       // We are resampling Opus internally to 32,000 Hz until all our
   4059       // DSP routines can operate at 48,000 Hz, but the RTP clock
   4060       // rate for the Opus payload format is standardized to 48,000 Hz,
   4061       // because that is the maximum supported decoding sampling rate.
   4062       playout_frequency = 48000;
   4063     }
   4064   }
   4065   return playout_frequency;
   4066 }
   4067 
   4068 int64_t Channel::GetRTT(bool allow_associate_channel) const {
   4069   RtcpMode method = _rtpRtcpModule->RTCP();
   4070   if (method == RtcpMode::kOff) {
   4071     return 0;
   4072   }
   4073   std::vector<RTCPReportBlock> report_blocks;
   4074   _rtpRtcpModule->RemoteRTCPStat(&report_blocks);
   4075 
   4076   int64_t rtt = 0;
   4077   if (report_blocks.empty()) {
   4078     if (allow_associate_channel) {
   4079       CriticalSectionScoped lock(assoc_send_channel_lock_.get());
   4080       Channel* channel = associate_send_channel_.channel();
   4081       // Tries to get RTT from an associated channel. This is important for
   4082       // receive-only channels.
   4083       if (channel) {
   4084         // To prevent infinite recursion and deadlock, calling GetRTT of
   4085         // associate channel should always use "false" for argument:
   4086         // |allow_associate_channel|.
   4087         rtt = channel->GetRTT(false);
   4088       }
   4089     }
   4090     return rtt;
   4091   }
   4092 
   4093   uint32_t remoteSSRC = rtp_receiver_->SSRC();
   4094   std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
   4095   for (; it != report_blocks.end(); ++it) {
   4096     if (it->remoteSSRC == remoteSSRC)
   4097       break;
   4098   }
   4099   if (it == report_blocks.end()) {
   4100     // We have not received packets with SSRC matching the report blocks.
   4101     // To calculate RTT we try with the SSRC of the first report block.
   4102     // This is very important for send-only channels where we don't know
   4103     // the SSRC of the other end.
   4104     remoteSSRC = report_blocks[0].remoteSSRC;
   4105   }
   4106 
   4107   int64_t avg_rtt = 0;
   4108   int64_t max_rtt= 0;
   4109   int64_t min_rtt = 0;
   4110   if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt)
   4111       != 0) {
   4112     return 0;
   4113   }
   4114   return rtt;
   4115 }
   4116 
   4117 }  // namespace voe
   4118 }  // namespace webrtc
   4119