Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / voice_engine / channel.cc
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
41 namespace webrtc {
42 namespace 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.
46 struct 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.
54 class 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
92 class 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
110 int32_t
111 Channel::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
157 int32_t
158 Channel::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
169 int32_t
170 Channel::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
184 int
185 Channel::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
228 int
229 Channel::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
273 void
274 Channel::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
297 void
298 Channel::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
308 void 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
317 void 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
326 void
327 Channel::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
356 int32_t
357 Channel::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
398 void
399 Channel::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
425 void
426 Channel::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
457 void
458 Channel::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
508 int32_t
509 Channel::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
561 bool 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
576 int32_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
719 int32_t
720 Channel::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
759 int32_t
760 Channel::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
781 void
782 Channel::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
791 void
792 Channel::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
801 void
802 Channel::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
825 void
826 Channel::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
842 Channel::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
968 Channel::~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
1049 int32_t
1050 Channel::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
1221 int32_t
1222 Channel::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
1242 int32_t
1243 Channel::UpdateLocalTimeStamp()
1244 {
1245
1246     _timeStamp += _audioFrame.samples_per_channel_;
1247     return 0;
1248 }
1249
1250 int32_t
1251 Channel::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
1278 int32_t
1279 Channel::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
1305 int32_t
1306 Channel::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
1334 int32_t
1335 Channel::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
1366 int32_t
1367 Channel::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
1380 int32_t
1381 Channel::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
1394 int32_t
1395 Channel::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
1412 int32_t
1413 Channel::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
1430 int32_t
1431 Channel::GetSendCodec(CodecInst& codec)
1432 {
1433     return (audio_coding_->SendCodec(&codec));
1434 }
1435
1436 int32_t
1437 Channel::GetRecCodec(CodecInst& codec)
1438 {
1439     return (audio_coding_->ReceiveCodec(&codec));
1440 }
1441
1442 int32_t
1443 Channel::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
1481 void
1482 Channel::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
1501 int32_t
1502 Channel::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
1518 int32_t
1519 Channel::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
1534 int32_t
1535 Channel::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
1626 int32_t
1627 Channel::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
1650 int32_t
1651 Channel::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
1699 int 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
1712 int32_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
1731 int32_t
1732 Channel::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
1754 int32_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
1804 bool 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
1823 bool 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
1853 bool 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
1861 bool 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
1877 int32_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
1907 int 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
1979 int 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
2057 int 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
2100 int 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
2108 int 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
2139 int 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
2208 int 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
2279 int 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
2309 int 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
2316 int 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
2394 int 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
2472 int 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
2502 void
2503 Channel::SetMixWithMicStatus(bool mix)
2504 {
2505     CriticalSectionScoped cs(&_fileCritSect);
2506     _mixFileWithMicrophone=mix;
2507 }
2508
2509 int
2510 Channel::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
2520 int
2521 Channel::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
2531 int
2532 Channel::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
2541 bool
2542 Channel::Mute() const
2543 {
2544     CriticalSectionScoped cs(&volume_settings_critsect_);
2545     return _mute;
2546 }
2547
2548 int
2549 Channel::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
2559 int
2560 Channel::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
2571 int
2572 Channel::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
2581 int
2582 Channel::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
2592 int 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
2614 int 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
2629 int
2630 Channel::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
2644 bool
2645 Channel::DtmfPlayoutStatus() const
2646 {
2647     return audio_coding_->DtmfPlayoutStatus();
2648 }
2649
2650 int
2651 Channel::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
2681 int
2682 Channel::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
2693 int
2694 Channel::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
2715 int
2716 Channel::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
2734 int
2735 Channel::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
2753 int
2754 Channel::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
2765 int
2766 Channel::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
2814 int
2815 Channel::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
2844 int
2845 Channel::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
2880 int
2881 Channel::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
2908 int
2909 Channel::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
2963 int
2964 Channel::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
3000 int
3001 Channel::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
3021 int
3022 Channel::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
3042 int
3043 Channel::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
3058 int
3059 Channel::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
3068 int
3069 Channel::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
3078 int Channel::SetSendAudioLevelIndicationStatus(bool enable, unsigned char id) {
3079   _includeAudioLevelIndication = enable;
3080   return SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id);
3081 }
3082
3083 int 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
3094 int Channel::SetSendAbsoluteSenderTimeStatus(bool enable, unsigned char id) {
3095   return SetSendRtpHeaderExtension(enable, kRtpExtensionAbsoluteSendTime, id);
3096 }
3097
3098 int 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
3108 int
3109 Channel::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
3124 int
3125 Channel::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
3135 int
3136 Channel::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
3150 int
3151 Channel::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
3176 int
3177 Channel::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
3269 int
3270 Channel::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
3322 int
3323 Channel::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
3361 int 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
3398 int
3399 Channel::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
3475 int 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
3504 int
3505 Channel::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
3531 int 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
3544 bool 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
3552 void 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.
3564 int Channel::ResendPackets(const uint16_t* sequence_numbers, int length) {
3565   return _rtpRtcpModule->SendNACK(sequence_numbers, length);
3566 }
3567
3568 int
3569 Channel::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
3602 int
3603 Channel::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
3628 bool
3629 Channel::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
3644 void 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
3659 uint32_t
3660 Channel::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
3669 void 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
3691 uint32_t
3692 Channel::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
3744 uint32_t
3745 Channel::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
3780 int 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
3818 int 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
3855 int 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
3873 int
3874 Channel::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
3886 void Channel::GetDecodingCallStatistics(AudioDecodingCallStats* stats) const {
3887   audio_coding_->GetDecodingCallStatistics(stats);
3888 }
3889
3890 bool 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
3905 int 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
3928 int
3929 Channel::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
3951 void 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
3988 int 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
4004 int
4005 Channel::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
4025 int
4026 Channel::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
4047 int
4048 Channel::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.
4059 int32_t
4060 Channel::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
4126 int32_t
4127 Channel::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
4180 int
4181 Channel::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
4254 int32_t
4255 Channel::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.
4273 void 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
4322 void
4323 Channel::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
4367 int 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
4394 void Channel::RemoveSecondarySendCodec() {
4395   audio_coding_->UnregisterSecondarySendCodec();
4396 }
4397
4398 int 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.
4409 int 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
4447 int 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
4457 int32_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
4478 int 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