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
47namespace webrtc {
48namespace voe {
49
50class 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
88class 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
117class 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.
150struct 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.
158class 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
193class 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
247int32_t
248Channel::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
295int32_t
296Channel::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
306int32_t
307Channel::OnRxVadDetected(int vadDecision)
308{
309    CriticalSectionScoped cs(&_callbackCritSect);
310    if (_rxVadObserverPtr)
311    {
312        _rxVadObserverPtr->OnRxVad(_channelId, vadDecision);
313    }
314
315    return 0;
316}
317
318bool 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
349bool
350Channel::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
381void 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
402void
403Channel::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
412void 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
418int32_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
455int32_t
456Channel::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
508bool 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
523int32_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
680int32_t
681Channel::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
720int32_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
741void
742Channel::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
751void
752Channel::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
761void
762Channel::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
785void
786Channel::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
802Channel::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
937Channel::~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
1008int32_t
1009Channel::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
1159int32_t
1160Channel::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
1180int32_t
1181Channel::UpdateLocalTimeStamp()
1182{
1183
1184    _timeStamp += static_cast<uint32_t>(_audioFrame.samples_per_channel_);
1185    return 0;
1186}
1187
1188void Channel::SetSink(rtc::scoped_ptr<AudioSinkInterface> sink) {
1189  CriticalSectionScoped cs(&_callbackCritSect);
1190  audio_sink_ = std::move(sink);
1191}
1192
1193int32_t
1194Channel::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
1221int32_t
1222Channel::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
1248int32_t
1249Channel::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
1277int32_t
1278Channel::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
1308int32_t
1309Channel::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
1322int32_t
1323Channel::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
1336int32_t
1337Channel::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
1354int32_t
1355Channel::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
1372int32_t
1373Channel::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
1383int32_t
1384Channel::GetRecCodec(CodecInst& codec)
1385{
1386    return (audio_coding_->ReceiveCodec(&codec));
1387}
1388
1389int32_t
1390Channel::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
1425void 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
1431void 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
1442int32_t
1443Channel::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
1460int32_t
1461Channel::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
1474int32_t
1475Channel::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
1566int32_t
1567Channel::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
1586int32_t
1587Channel::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
1635int 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
1648int 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
1661int32_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
1680int32_t
1681Channel::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
1703int32_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
1730bool 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
1749bool 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
1778bool 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
1786bool 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
1802int32_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
1836int 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
1908int 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
1986int 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
2026int Channel::IsPlayingFileLocally() const
2027{
2028    return channel_state_.Get().output_file_playing;
2029}
2030
2031int 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
2062int 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
2131int 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
2202int 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
2229int Channel::IsPlayingFileAsMicrophone() const
2230{
2231    return channel_state_.Get().input_file_playing;
2232}
2233
2234int 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
2312int 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
2390int 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
2420void
2421Channel::SetMixWithMicStatus(bool mix)
2422{
2423    CriticalSectionScoped cs(&_fileCritSect);
2424    _mixFileWithMicrophone=mix;
2425}
2426
2427int
2428Channel::GetSpeechOutputLevel(uint32_t& level) const
2429{
2430    int8_t currentLevel = _outputAudioLevel.Level();
2431    level = static_cast<int32_t> (currentLevel);
2432    return 0;
2433}
2434
2435int
2436Channel::GetSpeechOutputLevelFullRange(uint32_t& level) const
2437{
2438    int16_t currentLevel = _outputAudioLevel.LevelFullRange();
2439    level = static_cast<int32_t> (currentLevel);
2440    return 0;
2441}
2442
2443int
2444Channel::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
2453bool
2454Channel::Mute() const
2455{
2456    CriticalSectionScoped cs(&volume_settings_critsect_);
2457    return _mute;
2458}
2459
2460int
2461Channel::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
2471int
2472Channel::GetOutputVolumePan(float& left, float& right) const
2473{
2474    CriticalSectionScoped cs(&volume_settings_critsect_);
2475    left = _panLeft;
2476    right = _panRight;
2477    return 0;
2478}
2479
2480int
2481Channel::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
2490int
2491Channel::GetChannelOutputVolumeScaling(float& scaling) const
2492{
2493    CriticalSectionScoped cs(&volume_settings_critsect_);
2494    scaling = _outputGain;
2495    return 0;
2496}
2497
2498int 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
2523int 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
2538int
2539Channel::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
2569int
2570Channel::GetSendTelephoneEventPayloadType(unsigned char& type)
2571{
2572    type = _sendTelephoneEventPayloadType;
2573    return 0;
2574}
2575
2576int
2577Channel::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
2598int
2599Channel::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
2617int
2618Channel::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
2636int
2637Channel::VoiceActivityIndicator(int &activity)
2638{
2639    activity = _sendFrameType;
2640    return 0;
2641}
2642
2643#ifdef WEBRTC_VOICE_ENGINE_AGC
2644
2645int
2646Channel::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
2694int
2695Channel::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
2721int
2722Channel::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
2757int
2758Channel::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
2774int
2775Channel::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
2829int
2830Channel::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
2860int
2861Channel::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
2876int
2877Channel::GetLocalSSRC(unsigned int& ssrc)
2878{
2879    ssrc = _rtpRtcpModule->SSRC();
2880    return 0;
2881}
2882
2883int
2884Channel::GetRemoteSSRC(unsigned int& ssrc)
2885{
2886    ssrc = rtp_receiver_->SSRC();
2887    return 0;
2888}
2889
2890int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) {
2891  _includeAudioLevelIndication = enable;
2892  return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id);
2893}
2894
2895int 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
2906int Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) {
2907  return SetSendRtpHeaderExtension(enable, kRtpExtensionAbsoluteSendTime, id);
2908}
2909
2910int 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
2920void Channel::EnableSendTransportSequenceNumber(int id) {
2921  int ret =
2922      SetSendRtpHeaderExtension(true, kRtpExtensionTransportSequenceNumber, id);
2923  RTC_DCHECK_EQ(0, ret);
2924}
2925
2926void 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
2952void 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
2958int
2959Channel::GetRTCPStatus(bool& enabled)
2960{
2961  RtcpMode method = _rtpRtcpModule->RTCP();
2962  enabled = (method != RtcpMode::kOff);
2963    return 0;
2964}
2965
2966int
2967Channel::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
2981int
2982Channel::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
3004int
3005Channel::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
3079int
3080Channel::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
3131int
3132Channel::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
3165int 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
3200int
3201Channel::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
3260int 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
3289int
3290Channel::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
3309int 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
3322bool Channel::GetCodecFECStatus() {
3323  bool enabled = audio_coding_->CodecFEC();
3324  return enabled;
3325}
3326
3327void 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.
3341int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) {
3342  return _rtpRtcpModule->SendNACK(sequence_numbers, length);
3343}
3344
3345uint32_t
3346Channel::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
3355void 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
3370uint32_t
3371Channel::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
3424uint32_t
3425Channel::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
3458void 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
3469int 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
3507int 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
3544int 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
3562int
3563Channel::GetNetworkStatistics(NetworkStatistics& stats)
3564{
3565    return audio_coding_->GetNetworkStatistics(&stats);
3566}
3567
3568void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
3569  audio_coding_->GetDecodingCallStatistics(stats);
3570}
3571
3572bool 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
3584uint32_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
3591int Channel::LeastRequiredDelayMs() const {
3592  return audio_coding_->LeastRequiredDelayMs();
3593}
3594
3595int
3596Channel::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
3618int 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
3634int 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
3646int 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
3658int
3659Channel::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.
3668int32_t
3669Channel::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
3735int32_t
3736Channel::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
3789int
3790Channel::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
3864void 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.
3905void 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
3955void
3956Channel::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.
3999int 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
4037int 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
4047int32_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
4068int64_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