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